C++次期バージョンの言語拡張
コンセプト的な部分は置いておいて(ここが一番重要だけど)、時期C++であるC++0xのうち、言語部分の拡張をまとめてみる。
言語拡張は以下の3タイプ。
- templateエリアス
- concept
- 型推論する変数型auto
templateエリアス
template<class T> using Vec = vector<T,My_alloc<T>>;
ここは2点拡張が入っている。
concept
sort(v);
このsortの宣言は、
template<Container C> // sort container using < void sort(C& c); template<Container C, Predicate Cmp> // sort container using Cmp where Can_call_with<Cmp,typename C::value_type> void sort(C& c, Cmp less);
と書く、ここでは新たにconceptが導入されている。
- いままでtypenameやclassなどが入っていたところに、ContainerやPredicateといったconceptを指定して型を制約できるようになった
- たとえばCがContainer conceptを満たさないと、その旨のコンパイルエラーがでる
- 新たなwhere句で、conceptのCan_call_withを使ってCmpクラスとC::value_typeとの関連を制約できるようになった
conceptはtemplateで使うパラメータクラスを制約するものである。
このconceptは、これまでtemplateでライブラリを作ったときに、コンパイルエラーをわかりやすくするために入れていた、下記のようなチェック専用関数の代わりになる。
template<class TYPE> void TYPE_requires_Comparable() { #ifdef DEBUG TYPE a; TYPE b; int r = a < b; #endif } template <class ElemType> void sort(List<ElemType> l) { TYPE_requires_Comparable<ElemType>(); ... }
ちなみにこういう風に作っておけばg++だと以下のようなエラーになる:
xxx.cpp: In function `void TYPE_requires_Comparable() [with TYPE = Elem]': xxx.cpp:18: instantiated from `void sort(List<ElemType>) [with ElemType = Elem]' xxx.cpp:25: instantiated from here xxx.cpp:14: error: no match for 'operator<' in 'a < b'
concept(の定義方法)については以下の論文にある
concept Mutable_fwd<typename Iter, typename T> { Var<Iter> p; // a variable of type Iter. Var<const T> v; // a variable of type const T. Iter q = p; // an Iter must be copy-able bool b = (p != q); // must support ‘‘!=’’ operation, // and the resulting expression // must be convertible to ‘‘bool’’ ++p; // must support pre-increment, no // requirements on the result type *p = v; // must be able to dereference p, // and assign a ‘‘const T’’ to the // result of that dereference; no // requirements on the result type };
や
concept Small<typename T, int N> where sizeof (T) <= N { };
のように書くらしい。ほかにもいろいろ例がある。たとえば、関数中に明示的にassertを使ってその型がconceptを満たすかどうかチェックできたりなどできる。