当添加模板参数时,重载解析会产生歧义调用



在下面的代码中,编译器可以成功地将对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(...)时,过载#2和过载#4将是二义性的;字符串字面值参数将被推导为const char*T2(&)[I]

<<p> 原因/strong>

你的字符串字面值" "const char[8],这清楚地显示了它是如何被推断为过载#4的。然而,由于数组衰变成指针,const char[8]也是const char*,这显然可以推断出重载#2。

编译器通常会列出所有可能的重载,而不仅仅是有歧义的重载。所以重载1和3没有歧义。它们是二阶的。然而,重载2和重载4是一阶的——字符串文字是一个数组,数组衰减也是一阶的。

相关内容

  • 没有找到相关文章

最新更新