在你的第二种情况下,
std::cout << std::max("abc", "abcd") << std::endl
它们是字符串字面值,其中"abc"
的类型为char const [4]
,"abcd"
的类型为char const [5]
。
因此,在函数调用std::max("abc", "abcd")
中,std::max
必须推导出
auto max(char const (&a)[4], char const (&b)[5]) {
return a < b ? b : a;
}
由于std::max
没有接受不同类型的函数模板重载,因此这是不可能的。所以出现了错误!
警告!
如果在std::max
中显式地提到模板类型const char*
,那么它就可以被编译。 这是因为对于"abc"
和"abcd"
,类型也可以是const char*
,这是由于C++中的数组指针衰减导致的。
std::cout << std::max<const char*>("abc", "abcd" ) << '\n'; // compiles
^^^^^^^^^^^^^
此外,
std::max
的
std::initializer_list
重载将推断上述内容也作为模板类型,并且将其视为
const char*
。
std::cout << std::max({ "abc", "abcd" }) << '\n'
然而,你不应该这样做!
正如@AlanBirtles所指出的那样,这可能会导致未定义行为,因为std::max
将比较两个不同数组的指针。结果不能被中继并且应该执行上述操作。在比较中使用std::string
,就像你的第一个例子一样。使用字符串字面值(自C++14以来),您可以进行最小更改,并使第二个案例与第一个案例相同:
using namespace std::string_literals;
std::cout << std::max("abc"s, "abcd"s) << '\n';
顺便提一下,请参阅以下内容:
using namespace std;
结合使用,事情可能会变得非常奇怪。 - user4581301