標準C++:STLの基礎知識

【 評価    】★★★☆☆

【 難易度 】★★☆☆☆

【 ISBN    】4-7561-3804-7

豊富なソースコードからSTLの使い方を学べる貴重な本です。購読対象者はC++の入門書を理解した上で、STLを使いこなせていない人です。C++を学びたての頃に買って難しいと感じさせない本でした。

C言語では文字列をchar型の配列として使っています。しかし、char型の配列は固定長であり、拡張が困難でした。同様に何か構造体の配列を作成、その後になって要素を追加したりソートするは困難です。

その問題を効率を殆ど落とさずに解決したのがSTLです。C++を使ってSTLを使わないのは私には考えられません。理解しておくことを強く推奨します。

話がそれましたが、この本の特徴は豊富なサンプルがそのまま使える事でしょう。さらに、読みやすさに工夫がされており、ここまでSTLを段階的に学べる本は少ないと思います。

もう一つの特徴は、STLの内部実装をしる手助けになります。STLの有名どころでは、STLPortとVisual C++付属(Dinkumware)のものでしょう。前者はギリギリ読めますが、後者は常人が解析できるようなものではありません。本書はそれより読みやすいコードにイテレータ実装等の解説までついていますから、STLを真似して作ってみたい人にはもってこいです。

全体的にはライブラリの使い方に終始する本なので、高い評価は与えませんでしたが、役には立ちます。

つまり、初心者はいきなり「Effective STL」を読むより、こちらをお勧めします。

Leave a Reply

4 コメント - "標準C++:STLの基礎知識"

更新通知を受け取る »
avatar
並び替え:   新しい順 | 古い順 | 最も評価の多い
glanada
ゲスト

確かに、良い本だと思いますが、一カ所、誤りがあります。
p.138 にイテレータのサンプルがありますが、
ここで、
MyIterator& operator+(size_type n){
vp += n;
return( *this );
}
と書いてありますが、これでは、
MyIterator p = …
としたときに、
cout << *( p + 2 ) << endl;
cout << *( p + 3 ) << endl;
とすると、本来は、
cout << p[2] << endl;
cout << p[3] << endl;
が想定されるはずが、
cout << p[2] << endl;
cout << p[5] << endl; ←ここがおかしい
となります。
ちょっと、悩んでしまったので参考まで。

konuma
ゲスト

コメント有り難うございます。
初版のP.137でも同等の間違いがあることを確認しました。
「operator+()を一時変数を作らずに参照で返す」間違いですね。
# Effective C++で有名
# この著者がこの間違いをするのが驚き
確認したらerrataにも載っていないので、出版社に連絡したら図書券か雑誌くらいは届くかもしれません。試してみてはいかがでしょうか?
http://www.ascii.co.jp/books/support/4-7561-3121-2/errata/

glanada
ゲスト

ASCII に問い合わせて見ましたが、
やっと回答が来ました。まだ、正誤表には、
アップされていないようですので、ここに、
転記させてください。
———————————-
ご指摘をいただき有り難うございます。
ご指摘の問題は、operator+()とoperator-()の実装が間違ってoperator+=()と
operator-=()の実装になっていることが原因です(典型的なよくある間違いです)。
次の要領で、訂正してください。
1. 演算子の実装では、インスタンスの更新を行わず、代わりにコピーの一時的
なインスタンスを作成し、更新した上で、それを値渡し(戻り値の&をトル)で
返す。
2. 演算代入演算子の実装では、インスタンス自体を更新し、インスタンスを参
照渡し(戻り値に&を付ける)で返す。
加算演算子と減算演算子のオーバーロードを次のように訂正します。
// 二項加算演算子(このインスタンスを更新しない)
MyIterator operator+(size_type n) { // <— 値渡し
// 一時的なインスタンスを作成する
MyIterator temp = *this;
// tempを更新する
temp.vp += n;
// tempを値渡しで返す
return temp;
}
// 二項減算演算子(このインスタンスを更新しない)
MyIterator operator-(size_type n) { // <— 値渡し
// 一時的なインスタンスを作成する
MyIterator temp = *this;
// tempを更新する
temp.vp -= n;
// tempを値渡しで返す
return temp;
}
回答者:柏原 正三
———————————-

konuma
ゲスト

ご報告有り難うございます。
この手の実装はリファランスを知ったあとに、やたら高速化に拘る人が陥りがちです。
もうひとつ付け加えるとしたら、上記は
MyIterator temp(*this);
のが「書き方」としてスマートでしょうか。

wpDiscuz