3

如果我写,

int a=10,b=12;
int sub = b-a;

std::bitset<8*sub> bits(bitMask);

它给了我一个错误说

错误 C2975:“_Bits”:“std::bitset”的模板参数无效,预期的编译时常量表达式

如何克服这个错误,我想在运行时初始化 bitset,可以吗?还是有其他方法可以做到这一点?

4

4 回答 4

3

标准对您的问题的回答是使用std::vector<bool>,这是一个可以动态适应其大小的位设置。

请记住,这std::vector<bool>是一种允许以最节省内存的方式存储位的特(这就是它糟糕的原因:它不像其他s 那样表现。如果你想要一个真实,你不能。)std::vectorstd::vector<T>Tstd::vectorbool

接口保持相同(这也很糟糕,因为如果用 实例化,std::bitset 使用的通用代码会破坏地狱)vectorbool,所以你现有的代码不应该破坏。

专业化将std::vector<bool>在下一个标准中被弃用。如果您已经在使用 C++0x,正确的选择是std::dynamic_bitset. 如果您坚持使用当前的 C++ 标准,那么std::vector<bool>这就是您想要的。

于 2011-08-03T11:35:03.020 回答
3

模板参数必须是编译时常量。将模板视为代码生成器:必须在开始编译之前生成代码。您不能在“运行时”使用模板!

const unsigned int size = 10;
std::bitset<size> b;  // fine, the compiler knows what "size is"

unsigned int n; cin >> n;
std::bitset<n> c;     // doesn't make sense!

作为第一步,您应该const在代码中尽可能多地说明;您可能确实有编译时常量,但没有这样声明它们。

如果您确实需要具有动态大小的数据结构,则需要使用其他东西(例如,无符号字符向量以及按位访问器函数)。


这是一个非常简单的将位设置为字符向量的实现。我没有将其包装在一个类中,如果需要,您可以这样做:

std::vector<unsigned char> data;

bool getBit(size_t n, const std::vector<unsigned char> & data)
{
  if (data.size() * CHAR_BIT) <= n) return 0;

  return data[n / CHAR_BIT] & (1U << (n % CHAR_BIT));
}

void setBit(size_t n, std::vector<unsigned char> & data)
{
  if (data.size() * CHAR_BIT) <= n) data.resize(n / CHAR_BIT + 1, 0);

  data[n / CHAR_BIT] |= (1U << (n % CHAR_BIT));
}

// Exercise for the reader
void clrBit(size_t n, std::vector<unsigned char> & data);
void tglBit(size_t n, std::vector<unsigned char> & data);
于 2011-08-03T09:25:29.957 回答
1

boost::dynamic_bitset如果你想要一个......动态位集,你可以使用(我知道,很疯狂,对吧?)。

boost::dynamic_bitset<> bits(8 * sub, bitMask);
于 2011-08-03T10:56:53.293 回答
0

在你的情况下,你可以把 a 贴const在那里,所以它是 a constexpr

const int a=10,b=12;
const int sub = b-a;

std::bitset<8*sub> bits;

(来自评论)您不能在运行时初始化位集;这就是为什么它是模板参数或编译时常量

另一种方法是使用std::vector已包装在具有一些自定义访问功能的类中的布尔值

于 2011-08-03T09:26:47.943 回答