15

std::bitsetには、およびの を基にした文字列としてシリアル化するto_string()メソッドがあります。明らかに、これはビットセット内の各ビットに単一の 8 ビットを使用するため、シリアル化された表現が必要以上に 8 倍長くなります。 スペースを節約するために、ビットセットをバイナリ表現で保存したいと考えています。この方法は、ビットセットのビット数が 32 未満の場合にのみ関連します。私は何百も持っています。オブジェクトがPODであると想定しているため、オブジェクト(アドレス)自体で/ を使用したいかどうかわかりません。char10char
to_ulong()
memcpy()std::copy()

API は、アドレスを取得できた内部配列表現へのハンドルを提供していないようです。

バイナリ表現からビットセットを逆シリアル化するオプションも欲しいです。

これどうやってするの?

4

6 に答える 6

9

std::vector<unsigned char>これは、一度に 1 ビットずつ読み書きすることによる の明示的な作成に基づく可能なアプローチです...

template<size_t N>
std::vector<unsigned char> bitset_to_bytes(const std::bitset<N>& bs)
{
    std::vector<unsigned char> result((N + 7) >> 3);
    for (int j=0; j<int(N); j++)
        result[j>>3] |= (bs[j] << (j & 7));
    return result;
}

template<size_t N>
std::bitset<N> bitset_from_bytes(const std::vector<unsigned char>& buf)
{
    assert(buf.size() == ((N + 7) >> 3));
    std::bitset<N> result;
    for (int j=0; j<int(N); j++)
        result[j] = ((buf[j>>3] >> (j & 7)) & 1);
    return result;
}

逆シリアル化テンプレート関数を呼び出すには、関数呼び出しでbitset_from_bytesビットセット サイズNを指定する必要があることに注意してください。たとえば、

std::bitset<N> bs1;
...
std::vector<unsigned char> buffer = bitset_to_bytes(bs1);
...
std::bitset<N> bs2 = bitset_from_bytes<N>(buffer);

速度を本当に気にする場合、何かを得る 1 つの解決策は、たとえば一度に 1 バイトずつパッキングが行われるようにループの展開を行うことですが、さらに良いのは、内部を隠さない独自のビットセット実装を作成することです。を使用する代わりにバイナリ表現std::bitset

于 2011-09-18T19:41:54.070 に答える
1

完全性のために私自身の質問に答えます。

どうやら、これを行うための簡単ポータブルな方法はありません。

簡単にするために(効率ではありませんが)、to_string文字列のすべての32ビットチャンク(および残りの部分*)から連続する32ビットビットセットを作成し、to_ulongこれらのそれぞれでビットをバイナリに収集するために使用することになりました。バッファ。
このアプローチは、STL自体にビットをいじくり回しますが、これを行うための最も効率的な方法ではない可能性があります。

* は合計ビット数でテンプレート化されているため、残りのビットセットはいくつかの単純なテンプレートメタプログラミング演算を使用する必要があることに注意してください。std::bitset

于 2011-09-17T19:03:37.493 に答える
1

編集:以下は意図したとおりに機能しません。どうやら、「バイナリ形式」は実際には「バイナリの ASCII 表現」を意味します。


std::ostreamそれらをusingに書き込むことができるはずですoperator<<。それはここに言います:

[ビットセット] は、バイナリ形式のストリームから直接挿入および抽出することもできます。

于 2011-03-10T20:02:54.660 に答える
1

gamedev.net の人が提案しているように、ビットパック データの内部表現へのアクセスを許可するので、boost::dynamic_bitsetを使用してみることができます。

于 2011-10-11T13:24:41.633 に答える
0

文字列に変換し、8 文字のチャンクを単一のシリアル化されたバイトにグループ化する文字列の独自のシリアル化を行う以外に、明白な方法はわかりません。

編集:すべてのビットを反復処理しoperator[]、手動でシリアル化することをお勧めします。

于 2011-03-09T20:02:23.003 に答える