为什么用户定义的转换没有隐式地发生在调用对象上

Why user-defined conversion is not implicitly taking place on the calling object

考虑 AB 的以下 class 定义:

class A {
public:
   void func() const {}
};

class B {
public:
   // user-defined conversion operator to A
   operator A() const { return a_; }
private:
   A a_;
};

class A 定义了一个名为 func() 的 public 成员函数。 class B 没有,但它确实定义了一个 用户定义的转换运算符 到类型 A。这样,B 的实例可以 转换为 A 的实例。以下代码按预期工作:

B b;
static_cast<A>(b).func(); // call func() on temporary instance of A

在上面的代码中,转换运算符是通过 static_cast 命名转换 .

隐式调用的

请注意,B 中的转换运算符未指定为 explicit 以允许隐式转换。 但是,以下代码无法编译:

B b;
b.func(); // <-- error: 'class B' has no member named 'func'

正如错误消息所说,class B 没有名为 func 的成员,但是 class A 有,并且 class B 确实有一个到 A 的用户定义转换运算符。在这种情况下,用户定义的转换运算符是 not 隐式调用的。

为什么转换没有隐式完成?

成员访问不考虑转换 (§5.2.5/2 [expr.ref])。

In either case, the id-expression shall name a member of the class or of one of its base classes

这里的 id-expressionfunc()

因此编译器认为 func 必须是 B 的成员或 B 派生自的 class 的成员。不考虑向可能具有 func 成员的其他类型的隐式转换。