わお。C++ は、その奇妙さにいつも驚かされます。
テンプレート定義では、修飾されていない名前は依存ベースのメンバーを見つけられなくなりました (C++ 標準の [temp.dep]/3 で指定されているように)。例えば、
template <typename T> struct B {
int m;
int n;
int f ();
int g ();
};
int n;
int g ();
template <typename T> struct C : B<T> {
void h ()
{
m = 0; // error
f (); // error
n = 0; // ::n is modified
g (); // ::g is called
}
};
たとえば、名前の前に this-> を付けて、名前を依存させる必要があります。C::h の修正された定義は次のとおりです。
template <typename T> void C<T>::h ()
{
this->m = 0;
this->f ();
this->n = 0
this->g ();
}
別の解決策として (残念ながら GCC 3.3 との下位互換性はありません)、this-> の代わりに using 宣言を使用できます。
template <typename T> struct C : B<T> {
using B<T>::m;
using B<T>::f;
using B<T>::n;
using B<T>::g;
void h ()
{
m = 0;
f ();
n = 0;
g ();
}
};
それはあらゆる種類のクレイジーです。ありがとう、デビッド。
彼らが参照している標準 [ISO/IEC 14882:2003] の「temp.dep/3」セクションは次のとおりです。
クラス テンプレートまたはクラス テンプレートのメンバーの定義で、クラス テンプレートの基本クラスがテンプレート パラメーターに依存している場合、基本クラスのスコープは、クラスの定義の時点でも、非修飾名の検索中に調べられません。テンプレートまたはメンバー、またはクラス テンプレートまたはメンバーのインスタンス化中。[例:
typedef double A;
template<class T> class B {
typedef int A;
};
template<class T> struct X : B<T> {
A a; // a has typedouble
};
A
の定義の型名は、基本クラスで定義された typedef 名ではなく、グローバル名前空間スコープで定義された typedef 名にバインドX<T>
されますB<T>
。] [例:
struct A {
struct B { /* ... */ };
int a;
int Y;
};
int a;
template<class T> struct Y : T {
struct B { /* ... */ };
B b; //The B defined in Y
void f(int i) { a = i; } // ::a
Y* p; // Y<T>
};
Y<A> ya;
テンプレート引数のメンバーA::B
、A::a
、およびは、での名前のバインディングには影響しません。]A::Y
A
Y<A>