C/C++编程:使用字符串作为函数模板的实参

1060 篇文章 294 订阅

引入

有时候,把字符串传递给函数模板的引用参数会导致错误:由于长度的区别,这些字符串属于不同的数组类型。即applepeach属于char const[6], 而peacha属于char const[7]

解决方法是声明为非引用参数:对于非引用类型的参数,在实参演绎的过程中,会出现数组到指针的类型转换(这种转型被称为decay)

#include <string>
#include <iostream>

// 引用传参
template <typename T>
inline T const& maxref (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

//非引用传参
template <typename T>
inline T maxnoref(T a, T b){
    return  a < b  ?  b : a;
}

int main(void)
{
    std::string s;
 
    ::maxref ("apple", "peach");  // ok:相同的类型
    ::maxref ("apple", "peacha");   // error, 不同类型的实参
    ::maxref ("apple", s);  // error,不同类型的实参


    ::maxnoref ("apple", "peach");  //ok:相同的类型
    ::maxnoref ("apple", "peacha"); //ok:退化为相同的类型
    ::maxnoref ("apple", s);            // error,不同类型的实参
}

在这里插入图片描述

关于类型转换

#include <string>
#include <iostream>
#include <typeinfo>

// 引用传参
template <typename T>
void  ref (T const& x)
{
    std::cout << "x in ref(T const&): "
              << typeid(x).name() << '\n';   
}

template <typename T>
void nonref (T x)
{
    std::cout << "x in nonref(T):     "
              << typeid(x).name() << '\n'; 
}
int main(void)
{
    ref("hello");
    ref("helloaq");
    nonref("hello");
    nonref("helloaq");
}

在这里插入图片描述

怎么解决

没有通用的解决方法,根据不同的情况,采用下面不同的方法:

  • 使用非引用参数,取代引用参数(然而,这可能会导致无用的拷贝)
  • 编写接受引用参数和非引用参数的重载(可能导致二义性)
  • 对具体类型重载
  • 强制要求使用显示类型转换
  • 重载数组类型,比如:
#include <string>
#include <iostream>

template<typename T, int N, int M>
inline T const *maxref(T const (&a)[N], T const (&b)[M]){
    return  a < b  ?  b : a;
}

int main(void)
{
    std::string s;

    ::maxref ("apple", "peach");  // ok:相同的类型
    ::maxref ("apple", "peacha");   // ok
    ::maxref ("apple", s);  // error,不同类型的实参
}

总结

对于字符串,在实参演绎过程中,当且仅当参数不是引用时,才会出现数组到指针的类型转换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值