当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《从模板化父类访问继承变量》经验,为你挑选了1个好方法。

请考虑以下代码:

template class Foo
{
public:
  Foo() { a = 1; }

protected:
  int a;
};

template class Bar : public Foo
{
public:
  Bar() { b = 4; };

  int Perna(int u);

protected:
  int b;

};

template int Bar::Perna(int u) 
{ 
  int c = Foo::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::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 ++编译器也是如此.

新的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().



1> Andrew Grant..:

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

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

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

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

template 
int Bar::Perna(int u) 
{ 
  int c = Foo::a * 4; // This works
  c = this->a * 4; // and this

  using Foo::a; 
  c = a * 4; // and with 'using', so should this
}

(我实际上不是100%确定使用版本的正确语法,不能从这里测试,但你明白了).

推荐阅读
coco2冰冰
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有