接受 const char(&)[N] 的函数模板比接受 const T& 的函数模板更专业吗?

问题描述 投票:0回答:1

我定义了两个版本的函数模板,称为

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
具有相同的长度会导致歧义?

c++ c++11 overload-resolution function-templates compiler-bug
1个回答
2
投票

tldr; MSVC 接受呼叫是正确的

compare("dog", "cat");
。这是 gcc bug


情况 1:用于比较(p1, p2);

作者说

compare(p1, p2)
将调用第一个版本模板

上面引用的陈述是错误的,因为对于 const char 数组,版本 1 比版本 2 更专业。对于所有其他类型,第二个版本是可行的选择。因此,对于第一次调用compare(p1, p2)

,应选择第二个版本,因为第一个版本
甚至不可行


情况 2:用于比较("dog", "cat");

现在进行第二次通话

compare("dog", "cat")

 应使用第一个版本,因为它比第二个版本
更专业

也就是说,这似乎是 gcc 和 clang 的 bug。

GCC 拒绝使用字符串文字调用更专门的 const char 数组版本

© www.soinside.com 2019 - 2024. All rights reserved.