我有一组用于从 C 移植到 C++ 的程序中的位标志。
开始...
我的程序中的标志以前定义为:
/* Define feature flags for this DCD file */
#define DCD_IS_CHARMM 0x01
#define DCD_HAS_4DIMS 0x02
#define DCD_HAS_EXTRA_BLOCK 0x04
...现在我收集到常量(相对于类常量等)的#defines 通常被认为是错误的形式。
这引发了关于如何最好地在 c++ 中存储位标志以及为什么 c++ 不支持将二进制文本分配给 int 的问题,例如它允许以这种方式分配十六进制数字(通过“0x”)。这些问题总结在这篇文章的最后。
我可以看到一个简单的解决方案是简单地创建单个常量:
namespace DCD {
const unsigned int IS_CHARMM = 1;
const unsigned int HAS_4DIMS = 2;
const unsigned int HAS_EXTRA_BLOCK = 4;
};
我们称这个想法为 1。
我的另一个想法是使用整数枚举:
namespace DCD {
enum e_Feature_Flags {
IS_CHARMM = 1,
HAS_4DIMS = 2,
HAS_EXTRA_BLOCK = 8
};
};
但是让我感到困扰的一件事是,当涉及到更高的值时,它的直观性似乎……即
namespace DCD {
enum e_Feature_Flags {
IS_CHARMM = 1,
HAS_4DIMS = 2,
HAS_EXTRA_BLOCK = 8,
NEW_FLAG = 16,
NEW_FLAG_2 = 32,
NEW_FLAG_3 = 64,
NEW_FLAG_4 = 128
};
};
我们将此方法称为选项 2。
我正在考虑使用 Tom Torf 的宏解决方案:
#define B8(x) ((int) B8_(0x##x))
#define B8_(x) \
( ((x) & 0xF0000000) >( 28 - 7 ) \
| ((x) & 0x0F000000) >( 24 - 6 ) \
| ((x) & 0x00F00000) >( 20 - 5 ) \
| ((x) & 0x000F0000) >( 16 - 4 ) \
| ((x) & 0x0000F000) >( 12 - 3 ) \
| ((x) & 0x00000F00) >( 8 - 2 ) \
| ((x) & 0x000000F0) >( 4 - 1 ) \
| ((x) & 0x0000000F) >( 0 - 0 ) )
转换为内联函数,例如
#include <iostream>
#include <string>
....
/* TAKEN FROM THE C++ LITE FAQ [39.2]... */
class BadConversion : public std::runtime_error {
public:
BadConversion(std::string const& s)
: std::runtime_error(s)
{ }
};
inline double convertToUI(std::string const& s)
{
std::istringstream i(s);
unsigned int x;
if (!(i >> x))
throw BadConversion("convertToUI(\"" + s + "\")");
return x;
}
/** END CODE **/
inline unsigned int B8(std::string x) {
unsigned int my_val = convertToUI(x.insert(0,"0x").c_str());
return ((my_val) & 0xF0000000) >( 28 - 7 ) |
((my_val) & 0x0F000000) >( 24 - 6 ) |
((my_val) & 0x00F00000) >( 20 - 5 ) |
((my_val) & 0x000F0000) >( 16 - 4 ) |
((my_val) & 0x0000F000) >( 12 - 3 ) |
((my_val) & 0x00000F00) >( 8 - 2 ) |
((my_val) & 0x000000F0) >( 4 - 1 ) |
((my_val) & 0x0000000F) >( 0 - 0 );
}
namespace DCD {
enum e_Feature_Flags {
IS_CHARMM = B8("00000001"),
HAS_4DIMS = B8("00000010"),
HAS_EXTRA_BLOCK = B8("00000100"),
NEW_FLAG = B8("00001000"),
NEW_FLAG_2 = B8("00010000"),
NEW_FLAG_3 = B8("00100000"),
NEW_FLAG_4 = B8("01000000")
};
};
这是疯了吗?还是看起来更直观?我们称这个选择为 3。
回顾一下,我的首要问题是:
1. 为什么c++不支持“0b”值标志,类似于“0x”?
2. 定义标志的最佳样式是什么...
i。 命名空间包装的常量。
ii. 直接分配的无符号整数的命名空间包装枚举。
iii. 使用可读二进制字符串分配的无符号整数的命名空间包装枚举。
提前致谢!并且请不要主观地关闭这个线程,因为我真的想获得关于什么是最好的风格以及为什么 c++ 缺乏内置的二进制赋值功能的帮助。
编辑 1
一点额外的信息。我将从文件中读取 32 位位域,然后使用这些标志对其进行测试。因此,当您发布建议时请记住这一点。