用户定义的转换运算符模板和内置运算符:不匹配运算符

时间:2018-04-04 14:01:22

标签: c++ c++11 language-lawyer

考虑以下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 编译得很好。 DEMO

但是 GCC 失败了:

error: no match for 'operator+' (operand types are 'int' and 'A')
  return x + a;
         ~~^~~

问题:谁是对的?为什么?

1 个答案:

答案 0 :(得分:5)

我相信铿锵是对的。

要对+进行查找,因为至少有一个参数具有类类型,我们会考虑member, non-member, and builtin candidates。没有任何会员或非会员候选人,所以这已经足够了。 int operator+(int, int)有一个内置候选人,这是唯一的候选人。该候选项是可行的,因为A可以直接转换为int(我们有一个标准的从A转换为const A&的隐式对象参数,然后是用户定义的从那里转换为int,无需进一步转换)。由于我们有一个可行的候选人,这使得它成为最有可行的候选人。

请注意,如果A只有operator int() const { return 1; },则gcc会接受它。它只是无法考虑的转换函数模板