用户定义的转换运算符模板和内置运算符:与运算符不匹配 [英] User-defined conversion operator template and built-in operators: no match for operator
问题描述
请考虑以下MCVE.
#include <type_traits>
struct A {
template<typename T, typename std::enable_if<std::is_same<T,int>::value,int>::type = 0>
operator T() const { return static_cast<T>(1); }
};
int main() {
int x = 1;
A a;
return x + a;
}
clang 可以很好地进行编译. 演示
clang compiles it fine. DEMO
但是 GCC 失败并显示:
error: no match for 'operator+' (operand types are 'int' and 'A')
return x + a;
~~^~~
问题:谁是正确的人,为什么?
Question: who is right and why?
推荐答案
我相信clang是正确的.
I believe clang is right.
要在+
上进行查找,因为至少一个参数具有类类型,所以我们考虑成员,非成员和内置候选对象.没有任何成员或非成员候选人,所以这足够了.有 int operator+(int, int)
的内置候选.唯一的候选人.该候选者是可行的,因为A
可以直接转换为int
(我们对隐式对象参数进行了从A
到const A&
的标准转换,然后用户定义了从A
到int
的转换,无需进一步的转换).由于我们只有一个可行的候选人,因此这使其成为最可行的候选人.
To do lookup on +
, since at least one argument has class type, we consider member, non-member, and builtin candidates. There aren't any member or non-member candidates, so that's eay enough. There is a builtin candidate for int operator+(int, int)
, which is the only candidate. That candidate is viable because A
can be convertible to int
, directly (we have a standard conversion from A
to const A&
for the implicit object parameter, and then the user defined conversion from that to int
, there's no further conversion necessary). As we have one viable candidate, that trivially makes it the best viable candidate.
请注意,如果A
仅具有operator int() const { return 1; }
,则gcc会接受它.只是转换函数 template 不能考虑.
Note that if A
just had operator int() const { return 1; }
, gcc would accept it. It's just the conversion function template that fails to be considered.
这篇关于用户定义的转换运算符模板和内置运算符:与运算符不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!