template キーワード

RapidXML でのコンパイルエラー - Life like a clown で問題になっていた事がようやく解決できたのでメモ.

本題に入る前に.C++ では,typename キーワードは 2 通りの使い方があります.一つはテンプレート引数として 「型」を取ることを宣言する場合で,もう一つはテンプレートクラス内において,後続する記述が「型名」である事を明示する場合です.

typename には、もう一つ、後続する識別子が 「型名」であることを明示するという重要な働きがある。
・・・(中略)・・・

template<class T> class Foo {
public:
    void  foo() {
        T::value_type *p;
    }
};

ここで太字にした文は、ポインタ p の宣言ではなくて、 T::value_type と p の乗算とみなされてしまう。

このような時には、プログラマコンパイラに対して 「T::value_type は何かの型を表しているぞよ」 ということを教えてやる必要がある。そのためのキーワードが typename なのである。

http://www.fides.dti.ne.jp/~oka-t/cpplab-template-4.html

template キーワードにもこれと同じような役割があるようです.RapidXML でのコンパイルエラー - Life like a clown では,以下の記述が問題となっていました.尚,CharT はテンプレート引数で指定される型名です.

rapidxml::xml_document<CharT> doc;
doc.parse<0>(reinterpret_cast<CharT*>(&v.at(0)));

上記のように記述すると,コンパイラが parse<0> の部分を「テンプレート引数として 0 を指定した」ではなく,「parse は 0 未満である」と解釈してしまうためコンパイルエラーとなっていました.

$ g++-4 -I.. -Wall example_rapidxml.cpp 
example_rapidxml.cpp: In member function 'void xmlwrapper<CharT, Traits>::output(std::basic_istream<_CharT, _Traits>&) [with CharT = char, Traits = std::char_traits<char>]':
example_rapidxml.cpp:41:   instantiated from here
example_rapidxml.cpp:27: error: invalid operands of types '<unresolved overloaded function type>' and 'int' to binary 'operator<'

このような場合には,下記のように template キーワードを用いて,後続する記述がテンプレート関数である事を明示すれば良いようです.

rapidxml::xml_document<CharT> doc;
doc.template parse<0>(reinterpret_cast<CharT*>(&v.at(0)));

template キーワードのこの使い方は,今回初めて知りました.まだまだ知らない事が多いと痛感させられる出来事です.