[英]C++: Templated function return value
考虑以下代码:
#include <iostream>
using namespace std;
template <typename T>
T foo(T a, T b) {
if (a<b) {
return b;
}
return a;
}
int main() {
cout <<foo<int>(3,4) <<endl;
cout <<foo(1,2) <<endl;
cout <<foo("hello","goodbuy") <<endl; //>>>>>this line <<<<<<
cout <<foo<float>(3,4) <<endl;
}
它打印出来:4 2 hello 4但是当我用以下方法更改标记的行时:cout <('hello','goodbuy')<
warning: character constant too long for its type
cout <<foo<int>('hello','goodbuy') <<endl;
^
warning: character constant too long for its type
cout <<foo<int>('hello','goodbuy') <<endl;
^
并打印出来:4 2 1701604463 4为什么要打印出这么大的数字? 一些帮助或指导,请谢谢
主要问题:
'hello'
是一个表示整数的字符文字 ,如果该整数被接受(可以使用多少个字符取决于编译器)。 一次它被用来生成魔术数字 ,例如表示文件类型。 例如,在旧的DOS中,以字符MZ开头的文件是可执行文件,并且Windows命令解释器(虽然不是Windows资源管理器)仍然可以识别出这种愚蠢的魔力:
[H:\dev\test\0119] > [H:\dev\test\0119] > This version of H:\dev\test\0119\blah.txt is not compatible with the version of Windows you're running. Check your computer's system informa tion and then contact the software publisher. [H:\dev\test\0119] > _
在旧的C代码中,该数字可能由诸如'ZM'
的整数常量表示。
现在,从您的定义开始...
template< typename T >
T foo(T a, T b) {
if (a<b) {
return b;
}
return a;
}
让我先将其重写为我更喜欢的形式:
template< class Type >
auto foo( Type const a, Type const b)
-> Type
{ return (a<b? b : a); }
我这样做是在前面重写的,因此在下面可以忽略该方面。
无论形式如何,当实际参数为不同类型时(例如在调用foo( 3, 4.5 )
。 然后参数类型推导将失败,因此必须显式指定类型foo<double>( 3, 4.5 )
。 如何避免呢?
对于数字类型,您可以这样处理:
template< class Type1, class Type2 >
auto foo( Type1 const a, Type2 const b )
-> decltype( a + b )
{ return (a<b? b : a); }
现在,您要使用字符串文字作为参数来调用它。 它们将被推导为char const*
类型,然后a + b
表达式将无法编译。 因为您不能添加指针。
为此,仅比较指针值而不是字符串的字典比较, a<b
表达式可能会产生意想不到的结果。
一种解决方案是提供函数的重载:
auto foo( char const* const a, char const* const b)
-> char const*
{ return (strcmp( a, b ) < 0? b : a); }
然后,您可以像foo( "bravo", "alpha" )
一样调用它。
免责声明:所有C ++代码都不会被编译器所动。
正如@Brian所评论的那样,对字符串使用"
。否则,您将获得一个多字符文字(link1) (link2) 。
int main() {
cout << foo("hello","goodbuy") <<endl;
}
该代码可以编译,但是有问题! "hello"
和"goodbuy"
是字符数组,在作为参数传递时会转换为指向第一个字母的指针 。 因此,在模板函数中,您将比较两个指针,这绝对不是您想要的(因为此比较的返回值是不确定的)。 一种解决方案是将字符数组转换为std::string
。
#include <string>
int main() {
cout << foo<string>("hello", "goodbuy") <<endl;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.