我想了解,为什么 GCC 选择 f(char, A<C, 5> &var)
用于以下代码中的重载解析:
template <class C, int N> struct A { };
template <class C> struct A<C, 8> { static_assert(sizeof(C) > 8, "Assertion in A<C,8>"); };
template <class C> struct A<C, 5> { static_assert(sizeof(C) < 8, "Assertion in A<C,5>"); operator A<C,8>&(); };
template <class C> void f(double, A<C,8> &var);
template <class C> void f(char, A<C,5> &var);
int main(void)
{
A<int, 5> a;
f(4., a);
}
有两种重载可用:
template <class C> void f(double, A<C,8> &var);
4.
完全匹配double
(不需要隐式转换),但第二个参数需要用户定义的转换。所以这个重载:exact match
& user-define conversion
下一个重载,与GCC匹配:
template <class C> void f(char, A<C,5> &var);
4.
需要隐式转换为 char
但与 A<C,5>
完全匹配. GCC 选择这个重载而不是之前的重载有什么原因吗?
有人可以从标准第 13 节中找到有关此特定案例的证据吗?任何帮助或评论表示赞赏。谢谢!
最佳答案
演绎不能成功
template <class C> void f(double, A<C,8> &var);
和一个类型为 A<int, 5>
的参数. IE。没有可能的类型 C
这可以使A<C,8>
匹配参数类型 A<int,5>
.转换是可能的并不关心推论。
参见 [temp.deduct.call]/4。由于可以通过转换构造函数和转换函数来允许转换,因此不可能考虑(所有)转换以进行类型推导。这也可能导致歧义。
关于C++ 重载解析不明确 - GCC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21267059/