Ничего себе. C ++ не перестает удивлять меня своей странностью.
В определении шаблона неквалифицированные имена больше не будут находить членов зависимой базы (как указано в [temp.dep] / 3 в стандарте C ++). Например,
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), вы можете использовать вместо этого объявления ->:
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 ();
}
};
Это просто сумасшествие. Спасибо, Дэвид.
Вот раздел «temp.dep / 3» стандарта [ISO / IEC 14882: 2003], к которому они относятся:
В определении шаблона класса или члена шаблона класса, если базовый класс шаблона класса зависит от параметра-шаблона, область действия базового класса не проверяется при поиске безоговорочного имени либо в точке определения шаблона класса или члена или во время создания шаблона класса или члена. [Пример:
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>
. ]