Рассмотрим следующий код:
template<class T> class Foo
{
public:
Foo() { a = 1; }
protected:
int a;
};
template<class T> class Bar : public Foo<T>
{
public:
Bar() { b = 4; };
int Perna(int u);
protected:
int b;
};
template<class T> int Bar<T>::Perna(int u)
{
int c = Foo<T>::a * 4; // This works
return (a + b) * u; // This doesn't
}
g++ 3.4.6, 4.3.2 и 4.1.2 дают ошибку
test.cpp: In member function `int Bar<T>::Perna(int)':
test.cpp:25: error: `a' was not declared in this scope
g++ 2.96 и MSVC 6, 7, 7.1, 8 и 9 принимают его, как это делают (по крайней мере) более старые компиляторы Intel и SGI С++.
Выполняет ли новый компилятор Gnu С++ стандарт или нет? Если это так, то в чем смысл этого наследующего класса не может видеть защищенную унаследованную переменную-член?
Кроме того, если есть
int A() { return a; }
в Foo, я получаю ошибку
test.cpp:25: error: there are no arguments to A that depend on a template parameter, so a declaration of A must be available
test.cpp:25: error: (if you use -fpermissiveâ, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
когда я пытаюсь использовать его в функции-члене Bar. Мне также кажется, что это любопытно: Bar наследует Foo, поэтому я считаю очевидным, что A() в области Bar - Foo:: A().