为了账号安全,请及时绑定邮箱和手机立即绑定

从模板化父类访问继承变量

从模板化父类访问继承变量

C++
德玛西亚99 2019-08-02 17:23:24
从模板化父类访问继承变量请考虑以下代码: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 scopeg ++ 2.96和MSVC 6,7,7.1,8和9接受它,(至少)旧的Intel和SGI c ++编译器也是如此。新的Gnu C ++编译器是否遵守标准?如果他们这样做,继承类背后的基本原理是什么,无法看到受保护的继承成员变量?另外,如果有的话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,所以我认为Bar的范围内的A()显然是Foo :: A()。
查看完整描述

2 回答

?
慕斯709654

TA贡献1840条经验 获得超5个赞

后来的GCC版本正确实现了该标准。

该标准指定模板中的非限定名称是非依赖的,并且必须在定义模板时查找。当时未知依赖基类的定义(可能存在基类模板的特化),因此无法解析非限定名称。

对于在基类中声明的变量和函数名称都是如此。

正如您所观察到的那样,解决方案是提供变量或函数的限定名称,或者提供“使用”声明。例如

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%确定使用版本的正确语法,不能从这里测试,但你明白了)。


查看完整回答
反对 回复 2019-08-02
  • 2 回答
  • 0 关注
  • 482 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信