typenameが必要な理由

プログラミング言語C++』
 C.13.5 typenameとテンプレート



テンプレートを使ったプログラムでは、なぜ型名にtypenameを付ける必要があるのだろうか


以下のコードはどちらもエラーになる

template <class Container>
struct hoge {
    typedef Container::iterator iterator; // エラー
};

template <class Container>
void foo(Container& c)
{
    Container::iterator it; // エラー
}


テンプレートは使わなければコンパイル(コード生成)されないが構文エラーくらいは検出しなければならない

だが、構文チェックの時点でコンパイラはContainer::iteratorが「型」なのか「staticメンバ」なのか判別できない


そこで、以下のようにtypenameを付けることによって
Container::iteratorが型であることを明示化しなければならない

template <class Container>
struct hoge {
    typedef typename Container::iterator iterator; // OK
};

template <class Container>
void foo(Container& c)
{
    typename Container::iterator it; // OK
}


Visual C++だとtypenameを付けなくてもコンパイルが通ってしまうことが多いが
汎用コードを書く際はtypenameを付けるよう意識したほうがいい