C++ 是否可以通过按位操作指定返回类型?
我工作的公司的大部分代码经常对小数字使用无符号字符类型,以避免数据结构中不必要的填充。我很少看到这样的问题,但是在使用位运算符设置错误标志时,我遇到了隐式转换的小问题。我找到了一个简单明了的解决办法,但我想知道是否有更优雅的方式。顺便说一句,我们用c++11编译 给定以下错误代码枚举: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
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);
}