我正在使用枚举,并尝试重现一些示例from this页面。最初的示例按预期工作,但我通过以下代码得到了一些有趣的结果:
#include <iostream>
enum num : char {
zero = '0',
one = '1',
two = '2',
three = '3',
four = '4',
five = '5',
six = '6'
};
int main()
{
const char two = '2';
std::cout << two << std::endl;
std::cout << num::two;
return 0;
}
输出结果为:
2
50
我预计两个结果都是一样的,但num::two
似乎打印了一些其他值。此值也不会发生变化(50)
,因此我认为这不是随机/垃圾值&amp;有一些char / int解析正在完成,我不明白?这是the ideone link。
我知道我可以通过像zero = 0
这样分配来实现它,而不需要单引号就可以了。但是,我想知道幕后发生了什么,以及如何通过单引号分配控制可以打印的非单位数值。
答案 0 :(得分:14)
根据C ++标准(4.5积分促销)
4未编码枚举类型的prvalue,其基础类型为 fixed(7.2)可以转换为其基础类型的prvalue。 此外,如果积分促销可以应用于其基础类型, 其基础类型固定的未作用域枚举类型的prvalue也可以转换为升级的基础的prvalue 型强>
因此,应用积分促销并且运算符&lt;&lt;对于int类型的对象被调用。
答案 1 :(得分:10)
当您说enum num : char
时,您表示num
内部以char
实现,但仍然可以自动转换为整数值,即不必然char
。
正如您引用的页面所说:
未范围的枚举类型的值可以隐式转换为 积分类型。
请参阅Why does a value of an enum with a fixed underlying type of char resolve to fct(int) instead of fct(char)?,了解有关C ++标准关于整体推广与固定基础类型组合的措辞中的问题的有趣讨论。
在任何情况下,您都可以将整个事情想象成具有私有char
成员变量和公共int
转换运算符的类:
// very similar to your enum:
class num {
private:
char c;
public:
num(char c) : c(c) {}
operator int() const {
return c;
}
};
num two { '2' };
std::cout << two; // prints 50
要提高类型安全性并使std::cout
行出现编译错误,只需将enum
转换为enum class
:
enum class num : char
这与上面想象的class num
类似,但没有转换运算符。
当您将num
的实例提供给std::cout
时,您就是num
的客户端,并且逻辑上不认为输出格式将采用其内部{{1}考虑到实现。
要获得对输出格式的更多控制,您应该使用任何其他自定义类型,并为char
重载operator<<
。例如:
std::ostream
当然,枚举实例的特定#include <iostream>
enum class num : char {
zero = '0',
one = '1',
two = '2',
three = '3',
four = '4',
five = '5',
six = '6'
};
std::ostream& operator<<(std::ostream& os, num const& n)
{
switch (n)
{
case num::zero: os << "Zero"; break;
case num::one: os << "One"; break;
case num::two: os << "Two"; break;
case num::three: os << "Three"; break;
// and so on
}
return os;
}
int main()
{
std::cout << num::two; // prints "Two"
}
值现在变得毫无用处,所以你也可以完全摆脱它们:
char
这可能会让你觉得奇怪,但请记住,只有通用数字从0到6的枚举不是一个真实的用例。
答案 2 :(得分:7)
因为这两个调用两个不同的运算符重载:
第一个调用operator<<
和std::ostream
的非成员char
。这会打印出角色。
第二个示例由于整数提升而调用operator<<
成员int
,正如其他答案所解释的那样。
答案 3 :(得分:5)
原因是您的enum : char
与char
不同(这正是我们想要的 - 我们不希望枚举与其他类型相同,即使它们分配兼容 - 我们希望void func(num n)
与void func(char n)
不同,对吗?)。
因此,由于enum num
不是char
,因此将使用operator<<(int)
,并打印整数值,即使基础类型为char
。不完全合理,但我确定这就是发生的事情。