C++ 是否可以通过按位操作指定返回类型?

C++ 是否可以通过按位操作指定返回类型?,c++,c++11,casting,bit-manipulation,C++,C++11,Casting,Bit Manipulation,我工作的公司的大部分代码经常对小数字使用无符号字符类型,以避免数据结构中不必要的填充。我很少看到这样的问题,但是在使用位运算符设置错误标志时,我遇到了隐式转换的小问题。我找到了一个简单明了的解决办法,但我想知道是否有更优雅的方式。顺便说一句,我们用c++11编译 给定以下错误代码枚举: enum ErrorType : unsigned char { OK. = 0x00, ERROR01 = 0x01, ERROR02 = 0x02 }; 假设我有一些类型为e

我工作的公司的大部分代码经常对小数字使用无符号字符类型,以避免数据结构中不必要的填充。我很少看到这样的问题,但是在使用位运算符设置错误标志时,我遇到了隐式转换的小问题。我找到了一个简单明了的解决办法,但我想知道是否有更优雅的方式。顺便说一句,我们用c++11编译

给定以下错误代码枚举:

enum ErrorType : unsigned char
{
    OK.     = 0x00,
    ERROR01 = 0x01,
    ERROR02 = 0x02
};
假设我有一些类型为errorType的私有成员的类 将使用公共成员设置或取消设置标志,例如:

struct S
{
public:
void setError1();
void unsetError1();

private:
ErrorType errorType;
};
如果我尝试在下面隐式设置值:

void S::setError1()
{
    this->errorType |= ERROR01;
}
我得到类型转换错误

但是,如果我显式地强制转换按位转换,它就会工作

this->errorType = ErrorType(this->errorType | ERROR01);

问题似乎在于按位转换的输出总是一个整数,不一定反映输入类型。这是真的吗?如果是这样的话,有没有办法为它指定一个类型,这样我就不必每次都显式地强制转换?

是的,按位操作的结果是升级后的整数类型。当两个整数操作数参与算术运算时,它们首先被提升为至少一个
int
类型,其中运算在
int
s上执行,结果为
int
。没有从
int
到enum的隐式转换,因此您必须回溯自己


以下是有关整数提升规则的详细信息:

当不存在枚举的重载运算符时,按位操作采用内置运算符版本,将枚举提升为其参考底图类型后,可以显式强制转换为:

this->errorType = static_cast<ErrorType>(errorType | ERROR01);
问题似乎在于按位转换的输出总是一个整数,不一定反映输入类型。这是真的吗

从C语言的早期开始,对小于
int
类型的数学运算将把类型提升为
int

int
是“大整数类型”时,原因是升级到
int
会很便宜,并且可以防止一些溢出情况

如果是这样的话,有没有办法为它指定一个类型,这样我就不必每次都显式地强制转换

对!!定义操作,而不是接受默认生成的实现

ErrorType& operator |= ( ErrorType &left, ErrorType right )
{
    return left = ErrorType(left | right);
}

enum ErrorType:unsigned char
-您可能希望
enum class
在那里..创建您自己的
ErrorType&operator |=(ErrorType&a,ErrorType b)
@JesperJuhl不一定,但注意:标准中没有对
char
short
的操作。所有操作员至少在
int
上工作。因此,在操作之前,
char
被转换为
int
。操作结果与输入参数相同(转换后)。请参阅:注意最后一条规则:
两个操作数都提升为int
@dashwuff它是一个全局运算符,而不是一个成员运算符非常好。但我认为我们应该在这里微妙地指出问题所在。请注意,您并没有仅仅覆盖
运算符|
,因为除非您手动将参数转换为int,否则这将导致无限递归。必须小心地覆盖这些运算符,因为有自动转换在起作用,并且不总是很明显会发生什么。@PiotrSkotnicki,谢谢,我正要做出改变。@SergeyA无限递归在哪里?@PiotrSkotnicki我的错
ErrorType& operator |= ( ErrorType &left, ErrorType right )
{
    return left = ErrorType(left | right);
}