为什么 C++ 不能将 enum MyEnum : int
识别为 int
的协变体?
#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 class
和 enum struct
相对)提供对整数的隐式提升,即您可以这样做:
enum FooType : int { Crazy, Cool };
int val = Crazy; // promotion to integer
然而,这并不适用于相反的情况:
FooType val = 0; // illegal
这来自 §7.2/5:每个枚举都定义了一个不同于所有其他类型的类型,结合 §7.2/9:枚举器或对象的值无作用域枚举类型的通过整数提升转换为整数。
我相信这个规则的原因很明显:可以有(并且通常是)没有定义相应枚举器的整数值。在上面的示例中,转换 0
和 1
理论上是可能的,但转换 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 class
或 enum struct
)。
关于c++ - 虚函数返回的枚举协方差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13281437/