为什么 std::string 关系运算符比较结果对于模板和函数不同?

Why std::string relational operator comparison result is different for a template and a function?

在下面的代码中,模板和函数都比较两个字符串,return比较哪个更大。然而,尽管代码(定义体)相同,结果却不同。现在,它可能与采用字符串与字符串有关(这是 C++ 错误吗?)——但是为什么模板有区别?

#include <iostream>
#include <string>

std::string getBiggerStr(std::string a, std::string b);

template <class T>
T getBigger(T a, T b);

int main() {
    std::cout << "\t" << getBiggerStr("Amber", "John") << std::endl;
    std::cout << "\t" << getBigger("Amber", "John") << std::endl;

    return 0;
}

std::string getBiggerStr(std::string a, std::string b) {
    if(a > b) return a;
    return b;
}

template <class T>
T getBigger(T a, T b) {
    if(a > b) return a;
    return b;
}

结果:

        John
        Amber

为什么不一样?模板定义正文是从函数复制粘贴的!

getBigger("Amber", "John") 调用 getBigger<const char*> 其中 returns 哪个内存地址是更大的数字。

getBigger("Amber", "John") 函数调用中参数的类型(以及模板参数的类型)是 const char*。因此,该函数中的比较只是比较两个指针,这是 而不是 如何正确比较(按字典顺序)两个 C-style 字符串。

为了强制使用 std::string 作为 argument/template 类型,您可以将 operator ""s suffix 附加到文字:

using namespace std::string_literals;
int main() {
    std::cout << "\t" << getBiggerStr("Amber", "John") << std::endl;    // Automatic conversion to std::string
    std::cout << "\t" << getBigger("Amber"s, "John"s) << std::endl;     // Here, we need to explicitly specify
    return 0;
}

或者,如果您没有兼容 C++14 的编译器(operator ""s 需要),那么您可以显式构造两个 std::string 对象作为参数:

std::cout << "\t" << getBigger(std::string{ "Amber" }, std::string{ "John" }) << std::endl;