C++11では、新しくエイリアス宣言をテンプレート化できる。これを、エイリアステンプレートと呼ぶ。エイリアステンプレートは、エイリアス宣言をテンプレート化するのだから、簡単なメタ関数ならエイリアステンプレートだけで実装できるし、また、クラステンプレートを利用したメタ関数のラッパーとしても使える。
template < typename T > using add_pointer = typename std::add_pointer< T >::type ; template < typename T > void f( T ) { typename std::add_pointer<T>::type p1 = nullptr ; add_pointer<T> p2 = nullptr ; }
また、メタ関数にかぎらず、広くクラステンプレートをラップする目的にも使える。
template <class T, class Allocator = std::allocator<T> > using vector = std::vector< T, Allocator > ; template < typename T > void f( T ) { std::vector<T> v ; // これは簡単 typename std::vector<T>::iterator iter = v.begin() ; // なんじゃこりゃ? vector<T>::iterator iter = v.begin() ; // typenameなんて必要なし! }
こうしてみると、エイリアステンプレートのほうがメタ関数としてはるかに使いやすく感じる。余計なtypenameやら::typeやらが必要ないのだ。なぜ標準ライブラリはエイリアステンプレートを使わないのか。それには、TR1の設計段階では、エイリアステンプレートがッ規格上存在しなかったこともあろう。しかし、もうひとつ理由がある。ユーザーが特殊化を追加できないのだ。なぜならば、エイリアステンプレートには特殊化や部分的特殊化が存在しないからだ。ユーザー定義型に依存する型は、条件を満たせば、ユーザーが自由に特殊化を追加できる。それがクラスや関数のテンプレートの強みなのに、それができない。
これは、もし規格がエイリアステンプレートを使い、その実装方法を未規定にしていれば、ユーザーの特殊化を防ぐことができるという副次的な利点もある。C++11では、そのようなライブラリは入っていないのだが。
それに、規格はいつでも、ユーザーによる特殊化を、文面により明示的に禁止できる。だから、その目的でエイリアステンプレートを使う必要もない。
No comments:
Post a Comment
You can use some HTML elements, such as <b>, <i>, <a>, also, some characters need to be entity referenced such as <, > and & Your comment may need to be confirmed by blog author. Your comment will be published under GFDL 1.3 or later license with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.