http://d.hatena.ne.jp/Cryolite/20061222
なんで俺こんな血迷ったこと書いたんでしょうか?ちゃんと徹底的に調べて書けよヴぉけって感じ.
現在提案されている concept の仕様では,ある型が concept の要求を充足するかどうかを構造的に判定するか宣言的に判定するかを選ぶことができますよ〜,っていう.
auto concept Swappable< typename T > { void swap( T &&x, T &&y ); }; concept NothrowSwappable< typename T > : Swappable< T > {}; auto concept CopyAssignable< typename T > { T &operator=( T const & ); }; concept StronglyGuaranteedCopyAssignable< typename T > : CopyAssignable< T > {}; auto concept Destructible< typename T > { ~T(); }; concept NothrowDesctructible< typename T > : Destructible< T > {};
上の concept の宣言で auto キーワードが付いているものは,制約を構造的に充足するかどうかで concept の充足を判定する. auto キーワードが付いていない concept は各々の型に対して明示的に concept の充足を concept_map で宣言しないといけない.
上のコードで書いた concept の場合でいうと,ある型が Swappable かどうかは swap という関数が有効な式かどうかで判定される (structual) のに対して,ある型が NothrowSwappable であるかどうかは明示的に制約の充足を concept_map で宣言しないといけない (nominal) っていう. Swappable と NothrowSwappable には構造的な差異がなく意味的な差異しか存在しないので,こうすることでユーザが明示的に concept の充足を宣言する必要を最小限に抑えつつ,構造的に差異が無いけれど意味的に差異が存在するような concept (他の例として InputIterator と ForwardIterator とか) の充足を宣言することもできますよ〜,っと.
で,これをもうちょっと (ちょっとじゃない気もするけれど) 追求すると面白いことになるんじゃないでしょ〜か,っていう.
たとえば,下のコードのように汎用な holder を考えてみる.
template< class T > where Destructible< T > class Holder { public: where CopyConstructible< T > explicit Holder( T const &val ) : val_( val ) {} where Swappable< T > void swap( Holder &&x ) { swap( val_, x.val_ ); } where CopyAssignable< T > Holder &operator=( Holder const &rhs ) { swap( Holder( rhs ) ); return *this; } private: T val_; }; // class Holder template< class T > where NothrowSwappable< T > concept_map StronglyGuaranteedCopyAssignable< Holder< T > > {}; template< class T > where NothrowDestructible< T > concept_map NothrowDesctructible< Holder< T > > {};
上の Holder は, T が構造的に Assignable< T > や Destructible< T > を満たしていれば,各々構造的に CopyAssignable< Holder< T > > や Destructible< Holder< T > > を満たすのだけれど,これに加えて選択的な concept_map の宣言を仕掛けておくことによって, T が宣言的に NothrowSwappable< T > 満たしていれば自動で Holder< T > が StronglyGuaranteedCopyAssignable を充足して,また T が宣言的に NothrowDestructible< T > を充足していれば自動で Holder< T > が NothrowDestructible を充足するように宣言できるんちゃいます?ってゆー.
こういう使い方ができるなら,当然コンセプトに関する深い推論機構が欲しくにゃる気がする (なんて呼べばいいのかな?型推論に対応して制約推論とか?そんな機能をすでに持ってる言語あるのかな?) .たとえば,上のコードで T が NothrowSwappable でないにもかかわらず Holder< T > を StronglyGuaranteedCopyAssignable が要求される文脈に使ったときに, concept_map の選択的宣言から T を NothrowSwappable として宣言する選択肢を(Holder< T > を StronglyGuaranteedCopyAssignable として宣言する選択肢と並行して) 推論して提示するコンパイルエラーを吐くとか.ダメカナ?
C++ は型システムは汚いけれど型の型システムは今のところ綺麗なんだから,型の型システムに関しては型推論機構のような面白いものを色々乗せられる可能性があるんじゃないかというか,それはつまり型システムを動かせないために型の型システムに逃げてるだけじゃないかというか.