【问题标题】:Virtual explicit conversion operator overriding虚拟显式转换运算符覆盖
【发布时间】:2016-12-16 22:14:24
【问题描述】:

我有一个类 Base 定义了一个 explicit operator bool

struct Base {
    virtual explicit operator bool() const {
        return true;
    }
};

我有一个子类Derived,定义了一个operator bool

struct Derived : Base {
    operator bool() const override {
        return false;
    }
};

如您所见,Derived::operator bool 明确没有标记为explicit,而是标记为override,所以我希望编译器会抱怨。但是,gcc 和 clang 似乎都同意这是有效的。我的期望不合理吗?

此外,如果我使用如下类,TakesBool(base) 不会编译(如预期的那样),但TakesBool(derived) 可以:

void TakesBool(bool b) {}

int main() {
    //Base base;     TakesBool(base); // compilation error (as expected)
    Derived derived; TakesBool(derived);
    return 0;
}

这似乎表明Derived 有一个(非explicitoperator bool,但是,它被标记为override 而没有virtual 声明。这怎么可能?

【问题讨论】:

  • 关于派生类中不需要virtual,如果基类已标记为virtual,则它也隐含在所有派生类中。 override 关键字更多地是对编译器的提示,因此您不要尝试使用不同的签名来覆盖函数(例如在派生类中声明一个函数,该函数采用与基类中的函数不同的参数)。所以这些关键词与问题无关。
  • 虚拟调度仍然发生。 Base* pbase = &derived; TakesBool((bool)*pbase); 将调用 Derived::operator bool。我猜explicit 不被认为是函数签名的一部分,所以你可以用非explicit 覆盖explicit 转换。我不确定这种行为是否正确。
  • 这就像在基类中有一个protected: virtual 函数,而在派生类中有一个public: override。一点问题都没有。

标签: c++ c++11 operator-overloading overriding explicit


【解决方案1】:

您可能认为Derived 中的非explicit operator bool 不会覆盖Base 中的explicit operator bool,不,它确实explicit specifier 无关紧要,它不是函数签名的一部分。

来自标准,§10.3/2 Virtual functions [class.virtual]

(强调我的)

如果在类Base和类Derived中声明了一个虚成员函数vf,则直接或间接派生自Base,则一个具有同名的成员函数vf, parameter-type-list ([dcl.fct])、cv-qualification 和 ref-qualifier(或不存在) 声明为 Base::vf,则 Derived::vf 也是虚拟的(无论是否如此声明)并覆盖Base::vf

所以编译器只有在函数的名称、参数类型列表、cv-qualification 或 ref-qualifier 不匹配时才会抱怨,不会考虑显式说明符。


你说“标记override没有virtual声明”,注意派生类中成员函数的virtual声明是多余的,它也是virtual

【讨论】:

  • 我调查过是否有可能有一个同时具有explicit operator booloperator bool 的基类,并且这两者的处理方式不同。你知道如果派生类定义operator bool() override会发生什么吗?它会覆盖operator bools 吗?
  • @phimuemue 为什么不试试呢?
  • @underscore_d 是的,但我主要对基于标准的答案感兴趣。
  • @phimuemue 我不认为it 是可能的。您不能同时拥有explicit operator booloperator bool。重载?
  • @phimuemue 就在那里:explicit 不是签名的一部分。无论在层次结构中的位置如何,都不能声明具有相同签名的 2 个函数。尝试它会告诉你这个! songyuanyao 为 Clang 展示了同样的东西,这里是 GCC:coliru.stacked-crooked.com/a/f329d16b4b8ac66bmain.cpp:9:22: error: 'virtual Base::operator bool() const' cannot be overloaded explicit virtual operator bool() const ^~~~~~~~ main.cpp:4:13: error: with 'virtual Base::operator bool() const' virtual operator bool() const ^~~~~~~~
猜你喜欢
  • 2012-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-25
相关资源
最近更新 更多