meryngii.neta

今日も新たな"ネタ"を求めて。

クラステンプレート名は型名

クラステンプレートの中で自分のテンプレートを使うとき、テンプレート引数を省略することができる。
私はつい数か月前までこの仕様を知らなかった。

template <class T>
struct A
{
	static void f(A<T>);
	static void g(A);
};

一つ目のfはAをテンプレートとして扱い、テンプレート引数を与えている。しかし二つ目のgは何も与えていない。ここでコンパイルエラーになるのかと思いきや、何と上と同じくAと見なされる。
これはテンプレートの仕様として自明なものではないと思うが、知っているとたまに便利なこともある。もちろん、テンプレート引数に自分と別のものを指定したいときは省略できない。
Boost.Iteratorsでこれが使われている。

template <
    class Derived
  , class Value
  , class CategoryOrTraversal
  , class Reference  = Value&
  , class Difference = ptrdiff_t
>
class iterator_facade {
 /*...*/
protected:
    typedef iterator_facade iterator_facade_;
};

本来typedefの部分の型は

iterator_facade<Derived, Value, CategoryOrTraversal, Reference, Difference>

と書くはずだが、テンプレート引数の部分は省略できる。