std::forward_listにサイズがない


※見習いプログラマの意見です.全てのこの意見に対して疑ってください(安易に信じないでください).


std::forward_listとはC++0xに実装される単方向リストです.


C++0x forward_list - Faith and Brave - C++で遊ぼう


これはサイズを返すメンバ関数は持たないそうです.


理由は上記リンク先の記事にありますが,自分は正直2番で実装しても良いんじゃないかと思いますね.


1.確かに標準で実装してしまった場合,『クライアントがsizeが無くても良いから速く・小さいのが欲しい』と思った場合は標準を使えません.

2.標準で実装しなかった場合でクライアントがsizeが欲しい場合は,別途実装すればいいので標準を使えます.

// 2.の例

std::forward_list<int> slist;
std::size_t slist_size; // CAUTION!! これはslistのサイズだから必ず更新してね!


// こうしなくてもstd::forward_listをラップしてしまえば確実ですけど,上の例よりは面倒です.


でも,もしクライアントが1の様に『たった4バイトでも節約したい.pushやpop時のインクリメント・デクリメントのコストすら消したい』と思うなら,標準のstd::forward_listなんて使わないで自作すると思うんですよね.


(1リストにつき)4バイトのメモリと追加・削除のインクリメント・デクリメントが無視できないほどのオーバーヘッドになる可能性というのは殆ど無くないですか(STLを使う規模のプログラムで(組込みとかは除いて)).


# 結構あるんだったらすみません.
# サイズの確保が4バイトとは限らないですがw


方針が『Cの実装と比べてゼロオーバーヘッドを目指す』なので実装しないという選択もありだと思いますが,ちょっとオーバーじゃないのかなという感想です.


2.の場合でも結構コストがかかります.


上の例のようにする場合は

std::forward_list<int> slist;
std::size_t size;

// どこかで
assert(std::distance(slist.begin(), slist.end()) == size); // チェック!

// なんてすればReleaseでO(N)のコストがかからなかったり(でも完璧じゃないですが).


ラップクラスを作成する場合は,全部のメンバ関数に対して転送関数を定義とかしますからね.


でもC++0xでの新機能とか使えば簡単にできるのかな.

というか既存のC++の技術でも簡単にできたりしてw


●まとめ


1の場合が発生する確立×1の場合が発生した場合のコスト<2の場合が発生する確率×2の場合が発生したコスト


上式のように自分は思いました.

『1の場合が発生した場合のコスト』が結構でかいと思いますが,そういう場合はどっちにしろ自作しなきゃならないと思うので.


でもWriteGreatCodeとか読むと考えが変わるかもしれないです.

読みたい.