为什么用户定义的转换不会在调用对象上隐式发生

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

本文关键字:对象 调用 定义 用户 转换 为什么      更新时间:2023-10-16

考虑以下AB类定义:

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

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

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

在上面的代码中,转换运算符通过名为 caststatic_cast隐式调用。

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

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

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

为什么不隐式完成转换?

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

无论哪种情况,ID 表达式应命名类或其基类之一的成员

这里的id 表达式func()

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