用户定义的转换运算符模板和内置运算符:与运算符不匹配 [英] User-defined conversion operator template and built-in operators: no match for operator

查看:157
本文介绍了用户定义的转换运算符模板和内置运算符:与运算符不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下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(我们对隐式对象参数进行了从Aconst A&的标准转换,然后用户定义了从Aint的转换,无需进一步的转换).由于我们只有一个可行的候选人,因此这使其成为最可行的候选人.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆