这是一个安全的解决方法吗?我想使用 vector 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;
}
编辑: 感谢您提供其他解决方案的建议,但我真的希望对上述解决方案有一个明确的答案。感谢。
答案 0 :(得分:15)
我不确定std::basic_string<bool>
因为那会实例化std::char_traits<bool>
而我不确定标准是否需要定义,或者char_traits
主模板是否可以left undefined,只定义了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;
boolish
是一个简单的类型,因此只要boolish
数组与bool
数组具有相同的表示形式(您需要检查编译器,我使用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), "" );
}
答案 1 :(得分:3)
乔纳森周刊所说的一切。
但我会更简单:
我会用:
assert(sizeof(bool) == sizeof(char));
typedef std::vecor<char> vector_bool; // Now all the rest of your code works as expected
// without the need for a maker function.
答案 2 :(得分:1)
来自“Working C ++,2012-11-02”
21.1一般[strings.general]
1本条款描述了用于操纵任何非阵列POD(3.9)类型序列的组件。21.4.1 basic_string一般要求[string.require]
5 basic_string对象中类似char的对象应连续存储。也就是说,对于任何basic_string 对象s,身份&amp; *(s.begin()+ n)==&amp; * s.begin()+ n应保留n的所有值,使得0 &lt; = n&lt; s.size()。
但是
6引用basic_string序列元素的引用,指针和迭代器可能会被该basic_string对象的以下用法无效:
- 作为任何标准库函数的参数,将非const basic_string作为参数引用.233
- 调用非const成员函数,除了operator [],at,front,back,begin,rbegin,end和rend。
所以,只要你注意不要调用这些函数,你就应该安全,而在其他地方使用原始数组。
<强>更新强>:
字符特征和要求在 21.2 Character traits [char.traits] 和 21.2.1 Character traits requirements [char.traits.require] 中描述。此外,typedef和specializations分别在 21.2.2 traits typedefs [char.traits.typedefs] 和 21.2.3 char_traits specializations [char.traits.specializations] 中描述。 / p>
这些特征也用于输入/输出库。因此,eof()
或pos_type
和off_type
等要求在basic_string
的背景下没有意义。
除了char
,char16_t
,char32_t
和wchar_t
的四个专业之外,我认为实际上并没有要求实施这些特征。
虽然它与你的例子一起使用gcc 4.7开箱即用,我只用
定义了一个最小bool_traits
struct bool_traits {
typedef bool char_type;
static void assign(char_type &r, char_type d);
static char_type *copy(char_type *s, const char_type *p, std::size_t n);
static char_type *move(char_type *s, const char_type *p, std::size_t n);
};
采用了提供的默认实现(gcc 4.7),并使用了
std::basic_string<bool, bool_traits> ab;
您的环境可能已经提供了有效的实施方案。如果没有,您可以自己实施简单的bool_traits
或模板专业化std::char_traits<bool>
。
您可以在Working Draft, PDF或cppreference.com - std::char_traits中看到完整的角色特征界面。
答案 3 :(得分:1)
您也可以使用 boost::container::vector
。它与 std::vector
完全一样,但不是专门用于 bool
。