问题描述
请考虑以下代码:
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给出错误
g++ 3.4.6, 4.3.2 and 4.1.2 give error
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 c ++编译器也是如此。
g++ 2.96 and MSVC 6, 7, 7.1, 8 and 9 accept it, as do (at least) older Intel and SGI c++ compilers.
新的Gnu C ++编译器是否遵守标准?如果他们这样做,继承类的背后的理由是不能看到受保护的继承成员变量?
Do the new Gnu C++ compiler obey the standard or not? If they do, what is the rationale behind that inheriting class is not able to see a protected inherited member variable?
此外,如果有
int A() { return a; }
在Foo中,我收到错误
in Foo, I get error
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)
$ b b
当我尝试在Bar的成员函数中使用它。
我发现好奇:Bar继承Foo,所以我认为很明显,Bar范围内的A()是Foo :: A()。
when I try to use it in a member function of Bar.I find that curious as well: Bar inherits Foo, so I think it's obvious that A() in scope of Bar is Foo::A().
推荐答案
后来的GCC版本正确实现了标准。
The later GCC versions correctly implement the standard.
标准指定模板中的未限定名称不相关,必须在定义模板时查找。一个依赖基类的定义在那时是未知的(基类模板的特殊化可能存在),所以无法解析不合格的名字。
The standard specifies that unqualified names in a template are non-dependent and must be looked up when the template is defined. The definition of a dependent base class is unknown at that time (specializations of the base class template may exist) so unqualified names are unable to be resolved.
这是真的在基类中声明的变量和函数名。
This is true for both variable and function names declared in the base class.
正如你所观察到的,解决方案是提供变量或函数的限定名,或者提供一个 宣言。例如
As you have observed the solution is to provide the qualified name of the variable or function, or to provide a "using" declaration. E.g.
template<class T>
int Bar<T>::Perna(int u)
{
int c = Foo<T>::a * 4; // This works
c = this->a * 4; // and this
using Foo<T>::a;
c = a * 4; // and with 'using', so should this
}
不是100%确定使用版本的正确语法,不能从这里测试,但你得到的想法)。
(I'm actually not 100% sure about the correct syntax for the using version and can't test from here, but you get the idea).
这篇关于从模板父类访问继承的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!