繁体   English   中英

C ++:模板化函数的返回值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM