C++基础——使用字符串作为函数模板的实参
来源:互联网 发布:软件设计师考试真题 编辑:程序博客网 时间:2024/06/05 19:06
在<C++基础——一些细节、常犯错误的汇总>一文的细节3中,我们看到,
const char* s = "hello";
s
的类型是const char*
,"hello"
的类型是const char[6]
是数组类型,也就是与"hell"
(const char[5])具有不同的数据类型。
这一点在函数模板(以字符串为参数)的设计中,显得尤为重要。
template<typename T>inline const T& max(const T& x, const T& y){ return x > y ? x : y;}int main(int, char**){ ::max("hello", "world"); // 正确,具有相同的实参类型,const char[6], // 这样在类型推导时都能匹配到同一个类型 ::max("hello", "hell"); // 错误, 不同类型的实参 std::string s("world"); ::max("hello", s); // 错误, const char[6] 与 string是不同的类型 return 0;}
如果声明的是非引用参数,就可以使用长度不同的字符串作为max()的参数:
template<typename T>inline T max(T x, T y){ return x > y ? x : y;}int main(int, char**){ ::max("hello", "world"); // 正确,具有相同的实参类型,const char[6], // 这样在类型推导时都能匹配到同一个类型 ::max("hello", "hell"); // 正确, decay(退化)为相同的类型 std::string s("world"); ::max("hello", s); // 错误,不同的类型 return 0;}
产生在这种调用的原因是:对于非引用类型的参数,在实参演绎的过程中会出现数组到指针(pointer-to-array)的类型转换(这种转型通常也被称为decay),果真如此奇妙吗,我们不妨使用typeid
关键字加以验证:
template<typename T>void ref(const T& x){ cout << "x in ref(const T&): " << typeid(x).name() << endl; }template<typename T>void noref(T x){ cout << "x in noref(T): " << typeid(x).name() << endl;}int main(int, char**){ ::ref("hello"); // const char [6] ::noref("hello"); // const char* return 0;}
在上述的main函数中,分别将一个字符串(”hello”,类型为const char [6])传递给具有引用参数的函数模板和具有非引用参数的函数模板。通过打印的结果我们可以看到,参数为引用的函数模板和参数不是引用的函数模板在对待字符数组和字符串指针之间存在着一些隐蔽的不同。对这一问题并没有太好的方法,根据不同的情况,可以:
使用非引用参数,取代引用参数,
杀敌一千,自损八百,导致无用的拷贝
重载版本1,分别编写参数为引用类型地函数模板,和参数为非引用类型的函数模板
这可能会导致二义性的出现;
重载版本2,重载数组类型
template<typename T, int N, int M> // 存在两个非类型模板参数inline const T* max(const T (*x)[N], const T (*y)[M]){ return x > y ? x : y;}
事实上我们更倾向于使用,std::string
c++风格的字符串类,而不是c风格字符串类,这又牵涉到C++和C语言风格的问题了。C++是一种语言联邦,支持多编程范式。我们在之前的文章中有谈到,两种语言风格下的类型转换问题,<C++基础——C++风格的类型转换(static_cast、const_cast、dynamic_cast、reinterpret_cast>。
- C++基础——使用字符串作为函数模板的实参
- 使用字符串作为函数模板的实参
- C++ template -- 字符串作为函数模板实参
- 字符串作为函数模版实参的意外情况
- 字符串作为函数模版实参的特殊情况
- C语言中实参和形参问题&&函数使用数组作为参数的问题
- 模板类型实参和非类型实参的使用 ----- 基于模板的函数指针的使用
- C++ Template学习笔记之函数模板(3)——模板实参推演
- C++ Template学习笔记之函数模板(3)——模板实参推演
- 一个函数作为另一个函数的实参
- 【读书笔记】以函数作为算法的实参
- C++语法基础--模板实参推断,模板类型形参的实参的受限转换,模板实参推断与函数指针
- 流作为函数实参
- 数组作为函数实参
- string 作为函数实参
- C++ Template学习笔记之函数模板(4)——显式模板实参
- C++ Template学习笔记之函数模板(4)——显式模板实参
- C语言 变量作为函数定义中的实参写法
- Modify the /etc/apt/sources.list for Ubuntu
- C与C++中结构体的区别,C++中结构体和类的区别
- 蓝桥杯——2的幂次
- JAVA--接口
- accumulate函数
- C++基础——使用字符串作为函数模板的实参
- AxureRP7.0 MAC
- 栈的实现与应用
- 欢迎使用CSDN-markdown编辑器
- 获取SDCard存储大小
- ios多线程编程
- 利用XStream将List<String>转为xml后指定String的别名
- .NET WinForm中 一个 跨线程访问控件的示例(网络)
- 查看SDCard是否被挂载