質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

4回答

1675閲覧

bitset or vector<bool>

Seiten_Minagawa

総合スコア58

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2018/11/28 09:04

編集2018/11/28 09:07

※携帯からの投稿です

メモリを節約したい!

たくさんのbool型を扱おうとする時、bool型を構造体で大量に持ったりしてbool型1個1個が独立しているとbool型1個あたり1バイト消費してしまい、
1000個とか2000個のbool型を扱おうとすると、メモリが潤沢なPCではあまり問題になりませんが、Android(DXライブラリなど、C++でコーディングできるライブラリがあります)などメモリ容量が厳しい環境だと、問題になることがあります。

bitset? vector<bool>

bitsetか、vector<bool>を使うと、1ビット単位でbool型を扱うことができ、メモリを節約できます。
しかし、vector<bool>は特殊化されたvectorであって、vectorのようでvectorではなく、使わない方がいいという話があります。
一方、bitsetはコンパイル時点で要素数が確定していなければならず、実際に使う量が可変の場合、使わない部分が無駄になってしまいます。

どちらを使う……?

大量にbool型を扱いたく、bool型の数も可変にしたいが、メモリを節約したい(しなければならない)……と思った時、bitsetかvector<bool>、どちらを使うべきなのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

メモリを節約したい!

コンパイル時に最大ビット長を仮定できるなら std::bitset を、そうでないなら std::vector<bool> を使えばよいと思います。

非標準ライブラリも候補に入れられるなら boost::dynamic_bitset も検討ください。


しかし、vector<bool>は特殊化されたvectorであって、vectorのようでvectorではなく、使わない方がいいという話があります。

たしかに std::vector<bool> は微妙な問題を抱えており、時には失敗作と揶揄されることもありますが、ユースケースさえ適切であれば使えばよいと思います。(選定理由をコメントとして残しておいた方が、後々のトラブル回避にはよさそうですね。)

Is the use of std::vector<bool> objects in C++ acceptable, or should I use an alternative? 回答や、vector<bool> の話 記事もご参考までに。

投稿2018/11/28 09:48

編集2018/11/28 09:50
yohhoy

総合スコア6189

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Seiten_Minagawa

2018/11/28 12:18

bitset、vector<bool>のどちらにも一長一短あります。 私は基本的にoperator[]を使うので影響はないのですがどちらもイテレータを使えない……という問題があります。 メモリを節約しつつbool型を大量に使いたいとしましたが、もしかしたらbool型を1000個も2000個も使うような設計自体に問題があるのかもしれません……
yohhoy

2018/11/28 13:14

誤解されているのかもしれませんが、vector<bool>でもイテレータは*使えます*。通常コンテナのイテレータとの違いは、イテレータを介した要素アクセスがbool型領域を直接操作するのではなく、プロキシ型であるという点だけです。
guest

0

ベストアンサー

既に bitsetvector<bool> のおおざっぱな違いはわかっているようですので、それを元にどちらが__適切であるか__ (又は自分で独自のクラスを実装した方が良いのか) を判断してください。 トレードオフがあるので、どちらかが常に良いということはありません。

C++ では、型が満たさなければならない要求が色々と規定されています。 コンテナ型が満たさなければならない要求については、以下を参照してください。

https://en.cppreference.com/w/cpp/named_req/Container

vector<bool>reference がこの要件を満たすことが出来ません。 1 バイトの中に複数のオブジェクトを詰め込むことで容量を節約するようになっていますが、そうなると、要素が__固有のアドレス__を持つことができませんので、 vector<bool> の要素は bool& で表せないのです。 仲介する専用のクラスを通してやりとりするようなインターフェイスになっています。 それに派生して、イテレータが RandomAccessIterator の要件も満たしていません。

コンテナを操作するプログラム (ライブラリ) はコンテナ型の性質をあてにしているので、そういったものの中には vector<bool> が要件を満たしていない部分を使おうとしておかしくなることがあるかもしれません。 逆に言えば、そこさえ問題にならないのなら vector<bool> を避ける必要はありません。 通常の vector よりも機能が少し制限されるというだけのことです。

投稿2018/11/28 09:44

SaitoAtsushi

総合スコア5437

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Seiten_Minagawa

2018/11/28 12:09

bitsetとvector<bool>、どちらにも一長一短あるという印象なのですが、確かにvector<bool>はいくつかvectorの仕様に沿っていません。 個人的な予想ではdeprecatedになるか、他のvectorの仕様に沿うように1バイト消費するようになりそうと思っているので、現時点ではbitsetを使う方がいいのか……と考えています。 今後C++の仕様が改定されても1要素1ビットであることが保証されるなら、私は基本的にoperator[]を使うので、消費するメモリの点ではvector<bool>が有利になりますが……
Seiten_Minagawa

2018/11/29 09:18

ベストアンサーは悩みましたがわかりやすい解説をしてくださったSaitoAtsushiさんとさせていただきます。 皆さん回答ありがとうございました!
guest

0

どちらも使わず、バイト配列に任意のビットセット/ビットリセット/ビットチェックで実装すればいいかと

投稿2018/11/28 09:34

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KoichiSugiyama

2018/11/28 10:16

単なるフラグとして使うのであれば、構造体のビットフィールドを使うという手もありますね。 ループで初期化したりしたいのであれば、共用体でintのメンバーを持てば、intのビット長ぶんまとめてセットできますし。 今ほどメモリが潤沢でない時代はよく使っていました。
y_waiwai

2018/11/28 10:26

組み込みやマイコンなんかでは現役ですねっ bool bitbool(int n){return (bytearray[n/8]&(1<<(n%8)))!=0;}
guest

0

正直もう答えとしては出てる気がしますが質問者様が納得されていないようなので蛇足ながら

まず、Androidはメモリが少ないといっても
およそ10年前に発売されたHT-03Aでもカタログスペックを見るとRAM 192MBとなっています。
最新機種をみると、2GB~6GB ハイエンドに至っては8GBです。
1バイトを3000個分確保しても、たかだか3KBです。
神経質になる必要性があるほどメモリが枯渇しているようには思えません。

もちろん組み込み系で本当にメモリが枯渇している分野も存在しているとは聞きます。
ただ、3KBを惜しむような場面ではC++を採用する事自体が難しい気がします。


個人的な予想ではdeprecatedになるか、他のvectorの仕様に沿うように1バイト消費するようになりそう

その未来よりはAndroidの搭載メモリが増大する未来のほうが確率が高いと思いますよ

投稿2018/11/28 15:56

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Seiten_Minagawa

2018/11/29 09:45

確かに最近のAndroidはPCと遜色のないほどのメモリを持つ機種が増えています。 一方で、カタログスペックではGB単位のメモリを持っていても、そのほとんどをOSが使用しているため、カタログスペック通りにメモリを使えるわけでもありません。 しかし、GB単位のメモリを使うアプリはほぼないと思うので、この点はさほど問題にはならないと思いますが……
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問