一部のクラスのメンバー関数テンプレートと同じ名前のクラス テンプレートがあります。ここで、別の関数テンプレートが、問題のメンバー関数テンプレートを持つクラスの 1 つでインスタンス化されます。この関数テンプレート内でメンバー関数テンプレートを呼び出すには、template
キーワードを使用する必要があります。これは理解しており、問題はありません。ただし、クラス テンプレートではなくクラスのメンバー関数テンプレートを意味することを指定するには、スコープ解決演算子を使用する必要があります (それが呼び出されていることがわかりました) ::
。その理由はわかりません。
それは多くのテンプレート化されたものなので、例を挙げましょう:
//class with same name as member function below.
//must be class template or error doesn't show up.
//also no error if this is a function template instead of class
template <class T>
struct f
{
};
struct Base
{
//function with same name as struct above,
//no error if this is not templated
template <int N>
void f(){}
};
//template function that will be instantiated with T=Base.
//no error if this is not templated
template <class T>
void g(T t)
{
//I understand why template keyword is needed here,
//but not why T:: is needed
t.T::template f<0>();
//t.template f<0>(); gives error.
}
問題のエラーは (g++-4.7 から)
error: type/value mismatch at argument 1 in template parameter list for ‘template<class T> struct f’
error: expected a type, got ‘0’
コンパイラはf<0>()
、コメント化された行 (スコープ解決演算子なし) を type のオブジェクトをインスタンス化しようとして解析しているようstruct f<0>
です。なぜこれを行っているのかわかりませんt.template
。メンバー関数テンプレートにアクセスしようとしていることがわかるはずだと思いました。
ここで何が起こっているのかを理解したいT::
のですが、コンパイラをなだめる以外に、なぜこの場合に必要なのですか?
MSVC と Clang では問題ないようですので、g++ 固有の問題と思われます。