我定义了两个版本的函数模板,称为
compare
:
#include <cstring>
using namespace std;
// fist version
template <size_t N, size_t M>
int compare(const char (&a)[N], const char (&b)[M]) {
return strcmp(a, b);
}
// second version
template <typename T>
int compare(const T &a, const T &b) {
if (a < b) return -1;
if (b < a) return 1;
return 0;
}
int main() {
const char *p1 = "dog", *p2 = "cat";
compare(p1, p2); // call 1
compare("dog", "cat"); // call 2
return 0;
}
在《CPP Primer(第5版,使用c++11std)》一书中,作者说
compare(p1, p2)
将调用第一个版本模板,而compare("dog", "cat")
将调用compare
的第二个版本,因为它更多比第一个版本更专业。
但是,当我运行此代码时,出现编译器错误:
重载“compare(const char [4], const char [4])”的调用不明确
然后我把
compare("dog", "cat")
改成compare("dog", "cats")
,就可以毫无问题地调用第二版模板了
为什么
a
和b
具有相同的长度会导致歧义?
tldr; MSVC 接受呼叫是正确的
compare("dog", "cat");
。这是 gcc bug
作者说
将调用第一个版本模板compare(p1, p2)
上面引用的陈述是错误的,因为对于 const char 数组,版本 1 比版本 2 更专业。对于所有其他类型,第二个版本是可行的选择。因此,对于第一次调用compare(p1, p2)
,应选择第二个版本,因为第一个版本甚至不可行。
compare("dog", "cat")
应使用第一个版本,因为它比第二个版本更专业。 也就是说,这似乎是 gcc 和 clang 的 bug。