Programmingこの情報は恐ろしく昔のもので、現在のドラフト規格とまったくあっておりません。検索で飛んでこられた方は、この情報を信用せず、ご自分で規格をご確認ください。これは最高にためになる動画だ。コンセプトとは、C++のパラダイムのひとつ、ジェネリックプログラミングを、もっと分かりやすくするための文法だ。前半の5分ほどは、ジェネリックプログラミングはなんであるかを解説している。did.今のテンプレートは、複雑なトリックを多用しすぎている。多くのトリックは、本にも載っていない。C++ライブラリを書いている連中が何をやっているのかを知るためには、ニュースグループを調べなければならない。(原文が正しい自信がない)conceptには三つの機能がある。Difinitionsある型にたいする要求を定義する。ある型TはT:func()というメンバ関数を持っていなければならないとか、T::value_typeという型が定義されていなければならないなどだ。Clausesテンプレートパラメータに必要なコンセプトを明示的に指定できる。Map既存の型を、どのようにコンセプトの要求どおりに使うかを指定できる。個人的な感想は、恐ろしく賢いマクロか、恐ろしく便利なシンタックスシュガー。than演算子を持っていなければならないというコンセプトが示されている。than演算子(>)を使った場合は、コンパイラがエラーを出す。than演算子で比較できない型を渡した場合も、コンパイラはエラーをだす。コンパイラが吐くエラーは、「LessThanComparableの要求を満たしていません」等といった、人間に分かりやすいエラーだ。従来の、インスタンシエイトの過程を追っていくような、人間にとって暗号に近いエラーメッセージではない。それでは、LessThanComparableというconceptはどうやって定義するのか。;文法的な要求と、意味的な要求を定義できる。講演では、axiomについては詳しく述べていない。この機能はどうやって実現するのか疑問だ。本当に、これをコンパイル時にチェックできるのだろうか。than演算子がなければならないというものだ。現在のテンプレートパラメータのように、複数指定できる。;他にも、value_typeという型を持っていなければならない要求や、それらの型に対するコンセプトをネストして指定できる機能など。clauseは、次のように指定できる。InputIterator<Iter>::value_typeには、typenameの指定はいらないのかというものだ。ここは型を指定すると決まっているので、必要がない。コンパイラは適切に判断できる。次のようにすれば、conceptをサポートしていないコンパイラに対する、下位互換性も保てるだろう。;さて、28分あたりから、いよいよ、超強力なconcept_mapの解説に入る。先ほどのfindという関数は、イテレータに対しては問題なく対処できた。int型の配列に対してはどうだろう。int型の配列の先頭要素へのポインタは、十分にイテレータとして通用する。組み込み型であるので、value_typeやdifference_type等を持っていない。Mapを使い、どうやってコンセプトに合うようにするか、いわばマップを行う。Mapとは、How(如何にして)conceptの要求を満たすかを定義する。int型のポインタに、value_typeとdifference_typeが必要というのであれば、定義してやるだけだ。;とはいっても、組み込み型だけでも、かなりの数がある。いちいちひとつずつやっていくのは面倒だ。ここは、テンプレートを使うべきだ。;これで、すべてのポインタは、InputIteratorのコンセプトを満たすようになった。コンセプトは、階層構造にすることができる。Refinementという。iteratorランダムアクセスイテレータは、バイディレクショナルイテレータであり、インプットイテレータである。Resolutionに絡めることができるらしい。clauseがないが、これは簡便なショートカットシンタックスである。ワーオ!まず、最初のadvance関数は、非常にジェネリックで、どんなイテレータでも使うことが出来る。ランダムアクセスイテレータの場合、これは無駄が多すぎる。そこで、RandomeAccessIteratorのコンセプトを使ってやる。コンパイラは、ベストマッチを探してくれる。「である」ので、最初の関数にマッチする。Resolutionはややこしいというのに、さらに複雑になるのだろうか。Resolutionにかけられる。これだけでもややこしいというのに......。こんどは、あるコンテナの全要素をイテレートするというものだ。loopだが、これをどうするか。自分でやってもいいのだが、全要素をループさせるというのは、よくある操作なので、楽をしたい。他の言語はどのようにしているかというと。次のForコンセプトを満たす必要がある。;シンタックスシュガーにより、このように展開される。parentheseの間に空白がないのは、意識してやっているのだろうか。これをできるようにしようという提案がされているのだが。ひとつ、こんな風にコンセプトを明示的に使うことも出来るのだろうか。int型の配列に対しては、次のようにする。loopに書けることができる。既存の、既に問題なく動いているコードや、共通のフレームワークなどを変更せずにすむからだ。質問があるが、コンセプトはnamespaceの中に入る。ところで、STLのmultisetには、equal_rangeというメンバ関数がある。これは、引数として指定した値の範囲のイテレータを、pairで返す。loopに必要な情報は、すべてそろっている。やってForコンセプトに合わせるのか。ひとつひとつ、これを定義していくのは、面倒である。我々はすでに、Containerというコンセプトを定義した。;これで、Containerコンセプトを満たす型は、すべてforループにかけられる。テンプレートがらみのエラーメッセージに辟易としない人はいないはずだ。コンパイラは、インスタンシエイトの過程を追っていくので、エラーメッセージは膨大になり、人間が簡単に読めるものではなくなってしまう。内部の実装の詳細の識別子などがでてくるので、まずわけが分からない。}上記のコードの、VC8のエラーメッセージは次の通りである。宣言を確認してください。宣言を確認してください。宣言を確認してください。宣言を確認してください。この演算子または定義済の演算子に適切な型への変換の定義を行いません。宣言を確認してください。これをまともに読める人間は、まずいないだろう。次のようになれば、読みやすいのではないかと思う。「std::list::iteratorは、RandomAccessIteratorコンセプトを満たしていません。mapも見つかりません。他にも、インスタンシエイトされる前に、テンプレートのコードが、コンセプトにあったものかを、コンパイラがチェックすることができる。than演算子を使うことが出来ない。最後の質問でも出ているのだが、これらの機能にはコストがかかる。Boostのライブラリをふんだんに使ったコードのコンパイルには、かなりの時間がかかるが、コンセプトもテンプレートと同じく、かなり多くの処理を行わなければならない。仕様が確定するのが2009年で、ISOの認可がおりるのが、2010年、それから主要なコンパイルベンダーが実装するのに、数年はかかるだろうから、案外楽観視していいのかもしれない。ムーアの法則が続いていればの話だが。(Atom)C++11参考書C++11の参考書、アマゾンお気に入りリストを公開中。アマゾンの江添のほしい物リストC++11の参考書、C++の文法と機能をGitHubで公開中。EvangelistC++標準化委員会の委員ドワンゴ社員C++11本を執筆した。株式会社ドワンゴで働いている。江添のほしい物リスト筆者にブログのネタを提供するために、直接に品物を送りたい場合、住所をメールで質問してください。Texts.ただし、必要である範囲において他の著作物を引用していることがあります。