为什么用户定义的转换没有隐式地发生在调用对象上
Why user-defined conversion is not implicitly taking place on the calling object
考虑 A
和 B
的以下 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-expression 是 func()
因此编译器认为 func
必须是 B
的成员或 B
派生自的 class 的成员。不考虑向可能具有 func
成员的其他类型的隐式转换。
考虑 A
和 B
的以下 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-expression 是 func()
因此编译器认为 func
必须是 B
的成员或 B
派生自的 class 的成员。不考虑向可能具有 func
成员的其他类型的隐式转换。