在下面的代码中,编译器可以成功解析对 f()
的调用以调用 f(int&, const char*)
。
但是,对 g()
的调用是不明确的。它列出了所有四个重载作为可能的重载集。如果我从数组参数的模板参数列表中删除 , typename T2, std::size_t I
,然后对它们进行硬编码,则不会出现歧义,编译器会选择 g(T&, const char*)
.
添加两个模板参数如何使它变得模棱两可?我可以看到它如何通过衰减和转换解决任何一个重载,但我无法弄清楚添加这些模板参数是如何引入歧义的。
我已经在 Clang 3.8(未发布)和 VC++ 2015 上对此进行了测试。
#include <string>
void f(int&, const char*){}
void f(int&, char(&)[8]){}
void f(int&, bool){}
void f(int&, const std::string&){}
template <typename T>
void g(T&, bool){}
template <typename T>
void g(T&, const char*){}
template <typename T>
void g(T&, const std::string&){}
template <typename T, typename T2, std::size_t I>
void g(T&, T2(&)[I]){}
int main(int argc, char* argv[])
{
int i = 1;
f(i, " ");
g(i, " ");
return 0;
}
最佳答案
重载#2:
void g(T&, const char*){}
重载#4:
template <typename T, typename T2, std::size_t I>
void g(T&, T2(&)[I]){}
当使用字符串文字调用 g(...)
时,Overload #2 和 overload #4 会产生歧义;字符串文字参数将被推断为 const char*
以及 T2(&)[I]
。
原因
您的字符串文字 ""
是 const char[8]
,它清楚地显示了它是如何被推断为重载 #4。然而,由于数组衰减为指针,const char[8]
也是 const char*
,这显然推导了重载 #2。
关于c++ - 添加模板参数时,重载解析会产生不明确的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32853536/