(願わくば)ご存知のように、_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;
_
使用する - std::deque
配列が必要ない場合は、はい。
それ以外の場合は、 Boost Container のようなvector
に特化しない代替bool
を使用します。
それは興味深い問題です。
特殊化されていない場合に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演算子とデフォルトのコピーコンストラクターによって行われます。アルゴリズムを使用するときに想定どおりに反応するようにソートを追加しました。
すべてのケースに適しているかどうかはわかりません。あなたのニーズに合っていれば、ベクターのようなクラスを書き換えるよりも作業が少なくなります...
ニーズに依存します。私はどちらかに行きますstd::vector<unsigned char>
。ラッパーの作成は、機能のサブセットのみを使用する場合は問題ありませんが、そうでない場合は悪夢になります。
この問題にどう対処しますか? c_array()機能が必要です。
boost::container::vector<bool>
:
vector<bool>特殊化は非常に問題が多く、非推奨または標準から削除する試みがいくつか失敗しました。
Boost.Container
は、優れたBoost.DynamicBitsetソリューションがあるため、実装しません。...
boost :: container :: vector :: iteratorは実際のブール参照を返し、完全に準拠したコンテナとして機能します。 boost :: container :: vector<bool>機能のメモリ最適化バージョンが必要な場合は、Boost.DynamicBitset。
Vector <int>の使用を検討してください。一度コンパイルと型チェックを終えると、boolとintはどちらも単なる機械語になります(編集:これは常に正しいとは限りませんが、多くのPCアーキテクチャで当てはまります)。警告なしで変換する場合は、「bool foo = !! bar」を使用します。これは、ゼロをfalseに、非ゼロをtrueに変換します。
Vector <char>などはスペースを使用しませんが、文字はマシンのWordサイズよりも小さいため、状況によっては(非常に小さな)速度に達する可能性もあります。これが、boolがcharの代わりにintを使用して実装される主な理由だと思います。
明確なセマンティクスが本当に必要な場合は、独自のブール型クラスを作成することもお勧めします。
また、C++標準から削除されたvector <bool>特殊化を希望する人々のクラブへようこそ(それを置き換えるbit_vectorを使用)。それはすべてのクールな子供たちがたむろする場所です:)。
最も簡単な答えは、sb
が_vector<struct sb>
_である_struct {boolean b};
_を使用することです。次に、Push_back({true})
と言うことができます。良いように思える。
この問題はすでに discussed comp.lang.c ++。moderatedで発生していました。提案されたソリューション:
std::allocator
に基づく)および独自のベクトル特殊化。std::deque
を使用します(S. Mayersの書籍のいずれかで既に推奨されていました)-ただし、これは要件に合っていません。bool
ラッパーを作成します。char
と同じサイズの何か(int
/bool
/etc)を使用してくださいbool
;また、標準委員会の提案を見ました-マクロ(STD_VECTOR_BOOL_SPECIAL
のようなもの)を導入してこの専門化を禁止します-しかし、この提案はstl実装では実装されず、承認されませんでした。
あなたの問題にはこれをうまくやる方法がないようです...たぶんC++ 0xで。
私が推奨する回避策は、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 );