C++ C+;中标志的有符号与无符号变量的使用+;
是否有使用有符号变量和无符号变量作为标志的“良好实践”或习惯?就我个人而言,我会使用无符号变量,但在某些代码中甚至可以看到用于标志的有符号变量。我的意思是,特别是在图书馆界面中,它很重要 乌德帕特C++ C+;中标志的有符号与无符号变量的使用+;,c++,flags,C++,Flags,是否有使用有符号变量和无符号变量作为标志的“良好实践”或习惯?就我个人而言,我会使用无符号变量,但在某些代码中甚至可以看到用于标志的有符号变量。我的意思是,特别是在图书馆界面中,它很重要 乌德帕特 我不能接受“使用枚举”的答案,因为它是,而且它不能在库接口中使用。众所周知,标志总是非负整数,但为什么要使用int/无符号int/short/无符号short作为标志?使用#define,或者更好地使用enum类型 enum flags { FLAG0 = 0, FLAG1 = 1,
我不能接受“使用枚举”的答案,因为它是,而且它不能在库接口中使用。众所周知,标志总是非负整数,但为什么要使用
int
/无符号int
/short
/无符号short
作为标志?使用#define
,或者更好地使用enum
类型
enum flags
{
FLAG0 = 0,
FLAG1 = 1,
FLAG2 = 2,
...
FLAGN = n
};
我认为无符号类型是一组标志的更好表示形式。因为您需要特定数量的等效位来表示您的标志。在有符号类型中,第一位是特殊的 也许这也能满足你的要求。并将为您提供基本的逻辑运算符和转换方法
#include <iostream>
#include <bitset>
using namespace std;
int main() {
std::bitset<4> flags;
flags.set(1);
flags.set(3);
std::cout << flags.to_string() << std::endl;
std::cout << flags.to_ulong() << std::endl;
return 0;
}
#包括
#包括
使用名称空间std;
int main(){
std::位集标志;
标志集(1);
旗组(3);
std::cout如果您决定对标志使用enum,下面是一个有用的宏,它为您的enum类型的位运算符创建代码
#define GENERATE_ENUM_FLAG_OPERATORS(enumType) \
inline enumType operator| (enumType lhs, enumType rhs) \
{ \
return static_cast<enumType>(static_cast<int>(lhs) | static_cast<int>(rhs)); \
} \
inline enumType& operator|= (enumType& lhs, const enumType& rhs) \
{ \
lhs = static_cast<enumType>(static_cast<int>(lhs) | static_cast<int>(rhs)); \
return lhs; \
} \
inline enumType operator& (enumType lhs, enumType rhs) \
{ \
return static_cast<enumType>(static_cast<int>(lhs) & static_cast<int>(rhs)); \
} \
inline enumType& operator&= (enumType& lhs, const enumType& rhs) \
{ \
lhs = static_cast<enumType>(static_cast<int>(lhs) & static_cast<int>(rhs)); \
return lhs; \
} \
inline enumType operator~ (const enumType& rhs) \
{ \
return static_cast<enumType>(~static_cast<int>(rhs)); \
}
标志意味着它应该是一个枚举。@ Nim -对于我来说,FLAG不是一个枚举-因为旗子可以与按位操作符一起使用,比如<代码> > ,<代码>和<代码>和'~ ''。因为你不打算将变量用作小数,所以使用符号类型没有好处。你也可以考虑。除非你使用一个类型化的枚举。如果你使用C++。+库的接口(非外部“C”)您将无法使用不同编译器编译的库,而不是使用库的用户。C++ ABI从编译器到编译器甚至从版本到版本都不改变……不,不要使用<代码>定义< <代码>。请在另一时间读取用户2079303的注释,实际上需要多次读取它。众所周知,标志总是正整数,但事实并非如此。枚举的基础类型应是足够大的整数类型,以适合枚举的所有值;这通常是int
。此外,每个枚举类型应与char
或有符号
/无符号
整数类型兼容E.@纸鸟大师,好吧,也许我对“永远”这个词太过了。但是你见过负值标志吗?你听说过有人这样做吗?我认为可以肯定的是,众所周知,标志几乎总是正整数,因为你有2×10 ^ 9的正整数标志在C++中枚举。这也是一个很好的做法。@FilipKowalski是的,我在枚举中多次看到负值。enum e{UNKNOWN=-1,FOO=0,BAR=2,BAZ=4}无论如何,如果我们想确保EnUM基础类型的签名或不签名,我们应该移动到C++强大的枚举。对于那些懒得跟踪链接的人来说,有“-&”、“^”、“^”甚至“-[]”的重载。“。我宁愿使用std::undernative_type::type
而不是int.erm,auto three=Test(Test_1 | Test_2)
也能很好地与默认运算符配合使用……我使用的是C++03编译器,所以我的代码不包括C++11语法:)@Nim当然,但每次都需要键入cast。对我来说,它是函数(Test_1 | Test u 2)
vs函数(Test(Test|1 | Test|2))
所有这些操作符都是内联的,在运行时不应该花费任何成本。
enum Test
{
TEST_1 = 0x1,
TEST_2 = 0x2,
TEST_3 = 0x4,
};
GENERATE_ENUM_FLAG_OPERATORS(Test);
Test one = TEST_1;
Test two = TEST_2;
Test three = one | two;