C++ 重载解析在添加模板参数时产生不明确的调用
在下面的代码中,编译器可以成功地解析调用C++ 重载解析在添加模板参数时产生不明确的调用,c++,c++11,c++14,C++,C++11,C++14,在下面的代码中,编译器可以成功地解析调用f()调用f(int&,const char*) 然而,对g()的调用是不明确的。它将所有四个重载列为可能的重载集。如果我从数组参数的模板参数列表中删除、typename T2、std::size\u t I,并对它们进行硬编码,则不会出现歧义,编译器会选择g(t&,const char*) 为什么添加两个模板参数会使其变得模棱两可?我可以看到,尽管衰变和强制转换,它如何解决任何一个重载,但我无法理解添加这些模板参数是如何引入歧义的 我已经在Clang3.
f()
调用f(int&,const char*)
然而,对g()
的调用是不明确的。它将所有四个重载列为可能的重载集。如果我从数组参数的模板参数列表中删除、typename T2、std::size\u t I
,并对它们进行硬编码,则不会出现歧义,编译器会选择g(t&,const char*)
为什么添加两个模板参数会使其变得模棱两可?我可以看到,尽管衰变和强制转换,它如何解决任何一个重载,但我无法理解添加这些模板参数是如何引入歧义的
我已经在Clang3.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;
}
#包括
void f(int&,const char*){}
void f(int&,char(&)[8]){
void f(int&,bool){}
void f(int&,const std::string&){
模板
void g(T&,bool){}
模板
void g(T&,const char*){}
模板
void g(T&,const std::string&){
模板
空g(T&,T2(&)[I]){
int main(int argc,char*argv[])
{
int i=1;
f(i)“”;
g(i)“”;
返回0;
}
过载#2:
过载#4:
模板
空g(T&,T2(&)[I]){
当使用字符串文本调用g(…)
时,重载#2和重载#4将是不明确的;字符串文字参数将被推导为const char*
以及T2(&)[I]
原因
您的字符串literal
”
是const char[8]
,这清楚地显示了它是如何被推断为重载4的。然而,由于数组会衰减为指针,const char[8]
也是const char*
,这清楚地推断为重载#2。编译器通常会列出所有可能的重载,而不仅仅是不明确的重载。因此,重载1和重载3没有歧义。它们是二等品。但是,重载2和重载4是一阶的-字符串文字是数组,数组衰减也是一阶的 你说得对。我错过了数组重载中的const
。
void g(T&, const char*){}
template <typename T, typename T2, std::size_t I>
void g(T&, T2(&)[I]){}