【问题标题】:Why user-defined conversion is not implicitly taking place on the calling object为什么用户定义的转换不会隐式发生在调用对象上
【发布时间】:2017-11-25 17:16:45
【问题描述】:

考虑以下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

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

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

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

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

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

【问题讨论】:

  • 如果它有 30 个转换运算符呢?编译器应该尝试所有这些吗?如果它可以转换为两种都具有该方法的类型呢?编译器怎么能猜出你到底想做什么?假装你明确表达你的意图确实有意义。
  • @skypjack 是的,我认为编译器应该尝试所有这些,并且只有在有歧义时才会生成错误消息。
  • 幸运的是,委员会做出了不同的决定。 ;-)
  • 这是一个有趣的思想实验,考虑编译器尝试所有可能的转换的含义。
  • @skypjack 这是一个奇怪的论点。如果你写b(1)b+1等,编译器实际上会尝试所有30个转换运算符。 . 运算符只是有些不同。

标签: c++ type-conversion implicit-conversion


【解决方案1】:

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

在任何一种情况下, id-expression 应命名该类或其基类之一的成员

这里的id-expressionfunc()

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-30
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多