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;