c++ - 使用显式用户定义的强制转换运算符调用函数是不明确的

标签 c++ casting

我遇到了一个问题,这对我来说很难解释。这是最小的、可重现的代码,它在 GCC 6.2 和 Clang 3.9 上都失败了:

class T2;

class T1
{
    int field1;
public:
    T1(int pf) : field1(pf) {}
    operator int() { return field1; }
    operator T2();
};

class T2
{
    int field2;
public:
    T2(int pf) : field2(pf) {} 
};

T1::operator T2() { return T2(field1); }

void foo(T2 pt) {}

int main()
{
    T1 obj1(1);
    T2 obj2(2);

    foo((T2) obj1);             // ambiguous conversion for C-style cast from 'T1' to 'T2'
    foo(T2(obj1));              // ambiguous conversion for functional-style cast from 'T1' to 'T2'
    foo(static_cast<T2>(obj1)); // ambiguous conversion for static_cast from 'T1' to 'T2'
}

请注意,我没有编写从 T1 到 T2 的特定构造函数,所以我想编译器应该很清楚,唯一的方法是使用用户定义的强制转换运算符。

奇怪的是,当我注释掉一个看似无关的转换运算符时:

// operator int() { return field1; }

然后代码可以轻松编译。这是什么原因?

最佳答案

(T2) obj1T2(obj1) 的含义完全相同(或在本例中为 static_cast<T2>(obj1)),但可能更容易推理这种类似于构造函数的语法。

按原样使用代码,有两个选项:

  • 构建T2int , 由用户定义的转换运算符获得 int
  • 构建T2来自 T2由用户定义的转换运算符获得 T2

根据 N4140:

If there is exactly one viable function that is a better function than all other viable functions, then it is the one selected by overload resolution; otherwise the call is ill-formed

Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of the following rules applies:

  • User-defined conversion sequence U1 is a better conversion sequence than another user-defined conversion sequence U2 if they contain the same user-defined conversion function or constructor or they initialize the same class in an aggregate initialization and in either case the second standard conversion sequence of U1 is better than the second standard conversion sequence of U2.

由于这不适用,因此两种转化都不比另一种好。

关于c++ - 使用显式用户定义的强制转换运算符调用函数是不明确的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40380167/

相关文章:

python - 在 Python 中将字符串从 split 函数转换为 int 的有效方法

C++继承与抽象函数实现

c++ - 为什么我不能将 nullptr 转换为 weak_ptr<>

ios - 从 Parse 中获取子类对象

c++ - consteval 函数返回具有非平凡 constexpr 析构函数的对象

c++ - 比较 C++ 中的类类型

java - java变量类型问题

c++ - 捕获 C++ 文件 IO 期间所有错误(或 ios 对象中的任何错误)的最佳实践

c++ - 根据给定的概率分布从集合中提取值

c++ - 仅使用 boost 库中的属性树