哇。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),您可以使用 using 声明而不是 this->:
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
定义中的类型名称X<T>
绑定到全局命名空间范围中定义的 typedef 名称,而不是基类中定义的 typedef 名称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>