考虑以下简单示例。
当使用Clang编译时,会出现以下错误。
struct C
{
template <typename T> operator T () {return 0.5;}
operator int () {return 1;}
operator bool () {return false;}
};
int main ()
{
C c;
double x = c;
std::cout << x << std::endl;
}
当使用Clang编译时,会出现以下错误。
test.cpp:11:12: error: conversion from 'C' to 'double' is ambiguous
double x = c;
^ ~
test.cpp:4:5: note: candidate function
operator int () {return 1;}
^
test.cpp:5:5: note: candidate function
operator bool () {return false;}
^
test.cpp:3:27: note: candidate function [with T = double]
template <typename T> operator T () {return 0.5;}
^
1 error generated.
其他编译器也会生成类似的错误,例如GCC和Intel iclc。
如果我删除 operator int
和 operator bool
,它就可以编译并按预期工作。如果只删除其中一个,即保留模板运算符并保留 operator int
,那么非模板版本将始终被选择。
我的理解是,只有当模板和非模板重载函数相等时,即它们都是完美匹配或都需要相同的转换序列时,才会优先选择非模板版本。然而,在这种情况下,编译器似乎没有将操作符模板视为完美匹配。当同时存在 bool
和 int
重载时,它自然认为它们是有歧义的。
总之,我的问题是为什么在这种情况下操作符模板不被视为完美匹配?
f
的第二次调用显示完美匹配模板具有优先权。非模板优先权是第一和第三个调用。 - Yan Zhou