为什么`explicit`与`virtual`不兼容?

13
struct A
{
    // error C2216: 'explicit' cannot be used with 'virtual'
    virtual explicit operator bool() const 
    {
        return true;
    }
};

struct B : A
{
    // error C2216: 'explicit' cannot be used with 'override'
    explicit operator bool() const override 
    {
        return false;
    }
};

int main()
{
    if (A())
    {}

    if (B())
    {}
}

我的编译器是VC++ 2013 RC。

explicit为什么与virtual不兼容呢?

其中的原理是什么?


2
看起来是 MSVC 的 bug,因为在 gcc 和 clang 中运行良好。 - ForEveR
3
您可以使用NVI解决这个问题。 - Simple
1
https://connect.microsoft.com/VisualStudio/feedback/details/805301/explicit-cannot-be-used-with-virtual 在VC2017中仍未修复 - Predelnik
1个回答

18

看起来像是一个bug,因为以下引用证明它们确实是兼容的,并且我找不到任何不允许它的东西。

12.3.2 转换函数 [class.conv.fct]

2) 转换函数可以是explicit(显式的) [...]
[...]
5) 转换函数可以是virtual(虚拟的)。

7.1.2 函数说明符 [dcl.fct.spec]

5) 只有在非静态类成员函数的初始声明中才应该使用virtual(虚拟的)说明符;见10.3。
6) 只有在其类定义内的构造函数或转换函数的声明中应使用explicit(显式的)说明符;见12.3.1和12.3.2。


这个 bug 的原因可能是因为早期的 explicit 只能用于构造函数,而构造函数本身不能(或者不应该?)是虚函数,所以他们制定了一个额外的规则,禁止 virtualexplicit 同时使用,并且在 VC 2013 引入 explicit 操作符时没有更新这个规则。 - Christian Rau
是的,但为什么我不能在基类中创建一个虚拟构造函数,然后在实际类中实现它呢? - Melroy van den Berg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接