正如(希望)我们都知道,vector<bool>
完全被破坏,不能被视为c数组。获得此功能的最佳方法是什么?
到目前为止,我所想到的想法是:
vector<char>
或vector<bool_wrapper>
你们怎么处理这个问题?我需要c_array()功能。
作为一个附带问题,如果我不需要c_array()方法,如果我需要随机访问,解决此问题的最佳方法是什么?我应该使用deque还是别的什么?
编辑:
vector<bool>
是专门的,所以每个bool需要1位。因此,您无法将其转换为c风格的数组。当然,由于可能的对齐问题,我必须阅读my_bool :(
struct my_bool
{
bool the_bool;
};
vector<my_bool> haha_i_tricked_you;
答案 0 :(得分:38)
如果您不需要阵列,请使用std::deque
,是的。
否则请使用不专注于vector
的替代bool
,例如Boost Container中的{。}}。
答案 1 :(得分:20)
这是一个有趣的问题。
如果你需要一个std :: vector,如果它不是专门的,那么也许这样的东西可以适用于你的情况:
#include <vector>
#include <iostream>
#include <algorithm>
class Bool
{
public:
Bool(): m_value(){}
Bool( bool value ) : m_value(value){}
operator bool() const { return m_value;}
// the following operators are to allow bool* b = &v[0]; (v is a vector here).
bool* operator& () { return &m_value; }
const bool * const operator& () const { return &m_value; }
private:
bool m_value;
};
int main()
{
std::vector<Bool> working_solution(10, false);
working_solution[5] = true;
working_solution[7] = true;
for( int i = 0; i < working_solution.size(); ++i )
{
std::cout<< "Id " << i << " = " << working_solution[i] << "(" <<(working_solution[i] ? "true" : "false") << ")" <<std::endl; // i used ? : to be sure the boolean evaluation is correct
}
std::sort( working_solution.begin(), working_solution.end());
std::cout<< "--- SORTED! ---" << std::endl;
for( int i = 0; i < working_solution.size(); ++i )
{
bool* b = &working_solution[i]; // this works!
std::cout<< "Id " << i << " = " << working_solution[i] << "(" << (working_solution[i] ? "true" : "false") << ")" <<std::endl; // i used ? : to be sure the boolean evaluation is correct
}
std::cin.get();
return 0;
}
我用VC9试过这个,看起来效果很好。 Bool类的想法是通过提供相同的行为和大小(但不是相同的类型)来模拟bool类型。几乎所有的工作都是由bool操作符和默认的复制构造函数完成的。 我添加了一种排序,以确保它在使用算法时的假设作出反应。
不确定它是否适合所有情况。如果它适合您的需求,那么重写类似矢量的类就不那么重要了......
答案 2 :(得分:16)
取决于您的需求。我会选择std::vector<unsigned char>
。如果只使用功能的一部分,编写包装器就可以了,否则它将成为一场噩梦。
答案 3 :(得分:11)
你们怎么处理这个问题?我需要c_array()功能。
boost::container::vector<bool>
:
<强>矢量强>&LT;的 BOOL 强>&GT;专业化一直存在很大问题,并且已经有几次尝试不推荐地将其从标准中删除或删除。
Boost.Container
没有实现它,因为有一个优秀的 Boost.DynamicBitset 解决方案。...
所以 boost :: container :: vector :: iterator 返回真正的bool引用,并作为完全兼容的容器。如果您需要内存优化版本的 boost :: container :: vector &lt; bool &gt;功能,请使用 Boost.DynamicBitset 。
答案 4 :(得分:5)
考虑使用矢量&lt; int&gt;。一旦你通过编译和类型检查,bool和int都只是机器字(编辑:显然这并不总是正确;但在许多PC架构上都是如此)。如果您想在没有警告的情况下进行转换,请使用“bool foo = !! bar”,它将零转换为false,将非零转换为true。
载体&lt; char&gt;或类似的将使用更少的空间,但它也有可能在某些情况下(非常小的)速度命中,因为字符小于机器字大小。我相信,这是使用整数而不是字符来实现bool的主要原因。
如果你真的想要干净的语义,我也喜欢制作你自己的布尔类的建议 - 看起来像一个bool,就像一个bool,但是愚弄模板专业化。
此外,欢迎来到想要矢量的人的俱乐部&lt; bool&gt;专业化从C ++标准中删除(使用bit_vector替换它)。这是所有酷孩子们出去玩的地方:)。
答案 5 :(得分:4)
这个问题在comp.lang.c ++。moderated上已经discussed了。提出的解决方案:
std::allocator
)和自己的向量专业化; std::deque
(早在S. Mayers书籍中推荐) - 但这不符合您的要求; bool
包装; char
大小相同的内容(int
/ bool
/ etc)代替bool
; 同样早期,我看到了标准委员会的建议 - 介绍宏(类似STD_VECTOR_BOOL_SPECIAL
)以禁止此专业化 - 但AFAIK此提案未在stl实施中实施且未获批准。
似乎你的问题没有办法很好地做到这一点......也许在C ++ 0x中。
答案 6 :(得分:4)
最简单的答案是使用vector<struct sb>
sb
为struct {boolean b};
。然后你可以说push_back({true})
。看起来不错。
答案 7 :(得分:2)
我首选的解决方法是范围枚举的vector
,其基础类型为bool
。如果委员会不对它进行专门化,这将非常接近vector<bool>
。
enum class switch_status : bool { ON, OFF };
static_assert( sizeof( switch_status ) == 1 );
::std::vector<switch_status> switches( 20, switch_status::ON );
static_assert( ::std::is_same_v< decltype( switches.front() ), switch_status &> );
static_assert( ::std::is_same_v< decltype( switches.back() ), switch_status &> );
static_assert( ::std::is_same_v< decltype( switches[ 0 ] ), switch_status &> );
对于将演员表投向bool
的智慧,您将有自己的见解:
enum class switch_status : bool { OFF = false, ON = true };
static_assert( static_cast< bool >( switch_status::ON ) == true );
static_assert( static_cast< bool >( switch_status::OFF ) == false );
static_assert( static_cast< switch_status >( true ) == switch_status::ON );
static_assert( static_cast< switch_status >( false ) == switch_status::OFF );