解决vector <bool>的问题,使用basic_string <bool>?

Nei*_*irk 7 c++

这是一个安全的解决方法吗?我想使用向量bool,但需要传递指向期望C风格数组的旧代码的指针.

typedef std::basic_string<bool> vector_bool;

int main()
{
    vector_bool ab;
    ab.push_back(true);
    ab.push_back(true);
    ab.push_back(true);
    ab.push_back(false);
    bool *b = &ab[0];
    b[1] = false;
}
Run Code Online (Sandbox Code Playgroud)

编辑:感谢您提供其他解决方案的建议,但我真的希望对上述解决方案有一个明确的答案.谢谢.

Jon*_*ely 15

我不确定std::basic_string<bool>因为那将实例化std::char_traits<bool>,我不确定标准是否要求定义,或者char_traits主模板是否可以保持未定义,只有明确的特殊化,如char_traits<char>定义.您不能提供自己的专业化,char_traits<bool>因为如果专业化取决于用户定义的类型(bool显然不是),则只能专门化标准模板.也就是说,如果您的stdlib确实有一个默认char_traits定义,并且您不尝试使用需要成员char_traits执行任何有用操作的字符串操作,它可能会起作用.

或者,这是hacky但可能会工作:

struct boolish { bool value; };
inline boolish make_boolish(bool b) { boolish bish = { b }; return bish; }

std::vector<boolish> b;
b.push_back( make_boolish(true) );
bool* ptr = &b.front().value;
Run Code Online (Sandbox Code Playgroud)

boolish是一个普通的类型,所以只要一个数组boolish具有相同的表示形式bool(你需要检查你的编译器,我用a static_assert来检查没有填充)然后你可能会侥幸逃脱它,虽然它可能违反了别名规则,因为*ptr并且*++ptr不是同一个数组的一部分,所以递增指针并不指向下一个boolish::value它指向前一个的"超过结束"(即使这两个位置实际上具有相同的地址)虽然[basic.compound]/3似乎确实说++ptr"指向"下一个bool).

使用C++ 11,语法变得容易一些,你不需要make_boolish......

#include <vector>
#include <assert.h>

struct boolish { bool value; };

int main()
{
  std::vector<boolish> vec(10);
  vec.push_back( boolish{true} );
  bool* ptr = &vec.front().value;
  assert( ptr[10] == true );
  ptr[3] = true;
  assert( vec[3].value == true );

  static_assert( sizeof(boolish) == sizeof(bool), "" );
  boolish test[10];
  static_assert( sizeof(test) == (sizeof(bool)*10), "" );
}
Run Code Online (Sandbox Code Playgroud)