c++ - 虚函数返回的枚举协方差

标签 c++ enums c++11 covariance

为什么 C++ 不能将 enum MyEnum : int 识别为 int 的协变体?

示例:http://ideone.com/Ns1O2d

#include <iostream>

enum FooType : int
{
    Crazy = 0,
    Cool
};

enum BarType : int
{
        Hello = Cool + 1,
        World
};

class Foo
{
public:
        Foo(void)
        {
        }

        ~Foo(void)
        {
        }

        virtual int getType(void) 
        {
                        return Crazy;
        }
};

class Bar : public Foo
{
public:
        Bar(void)
        {
        }

        ~Bar(void)
        {
        }

        virtual BarType getType(void)
        {
                return Hello;
        }
};

int main(int argc, char* argv[])
{
        Bar f = Bar();           
        std::cout << f.getType() << std::endl;
        return 0;
}

编译错误:

prog.cpp:43:18: error: conflicting return type specified for 'virtual BarType Bar::getType()'
prog.cpp:26:14: error:   overriding 'virtual int Foo::getType()'

最佳答案

非作用域枚举类型(即通常的 enums ,与 enum classenum struct 相对)提供对整数的隐式提升,即您可以这样做:

enum FooType : int { Crazy, Cool };
int val = Crazy; // promotion to integer

然而,这并不适用于相反的情况:

FooType val = 0;  // illegal

这来自 §7.2/5:每个枚举都定义了一个不同于所有其他类型的类型,结合 §7.2/9:枚举器或对象的值无作用域枚举类型的通过整数提升转换为整数。

我相信这个规则的原因很明显:可以有(并且通常是)没有定义相应枚举器的整数值。在上面的示例中,转换 01理论上是可能的,但转换 2或无法转换任何更大的数字。

但是,如果枚举与其基础类型协变(在您的示例中为 int),在您定义它的意义上,以下是可能的:

class Foo
{
public:
  virtual ~Foo(void) {}
  virtual int getType(void) 
  {
    return Crazy;
  }
};

class Bar : public Foo
{
public:
  virtual ~Bar(void) {}
  virtual BarType getType(void)
  {
    return Foo::getType();
  }
};

在派生类中,Bar::getType()现在已被定义为返回 BarType , 但它是通过调用继承函数 Foo::getType() 来实现的,这是完全合法的。

如果这在书面上是可能的,Bar::getType()将不得不隐式转换 int结果来自 Foo::getType()int .如上所述,这是不可能的。


但是,您仍然可以通过声明 Bar::getType 来实现您的代码似乎想要实现的目标。与Foo:getType相同, 并返回 BarType (隐式提升为 int ):

class Bar : public Foo
{
public:
  virtual ~Bar(void) {}
  virtual int getType(void)
  {
    return Hello;
  }
};

请注意,这仅在基础类型为 int 时有效(这是因为您在枚举声明中将其固定为 int),并且如果枚举未限定范围(即不使用 enum classenum struct)。

关于c++ - 虚函数返回的枚举协方差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13281437/

相关文章:

c++ - 模板化赋值运算符模板实例化失败

c++ - ORA-00904 : "E_MAIL": invalid identifier

c++ - Qpushbutton 未显示

c# - 是否可以将数据绑定(bind)到枚举并显示用户友好的值?

java - 使用实现接口(interface)的枚举的 EnumSet

c# - 是否可以创建一个包含数组的枚举?

c++ - Qt 链接到 Ovi(Nokia) Store 商店

c++ - {fmt}等同于cout.rdbuf?

带有 lambda 比较器错误的 C++ priority_queue

c++ - 重载抽象运算符时出现 Clang 链接器错误=