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

标签 c++ inheritance templates

<分区>

考虑以下代码:

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 c++ 编译器也接受它。

新的 Gnu C++ 编译器是否符合标准?如果他们这样做,继承类无法看到 protected 继承成员变量背后的基本原理是什么?

还有,如果有

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()。

最佳答案

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

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

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

如您所见,解决方案是提供变量或函数的限定名称,或提供“using”声明。例如

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% 确定所使用版本的语法是否正确,也无法从这里进行测试,但你明白了)。

关于c++ - 从模板化父类访问继承变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15002270/

相关文章:

java - ArrayList 和 Arrays.asList 在继承情况下对 Collection 的工作方式不同

c++ - 如何通过可变构造函数调用复制构造函数?

c++ - 定义外联成员模板函数

C++ WINSOCK tcpaccept 在 "attack"之后停止接受连接

c++ - 使用 c++0x Lambda 表达式时调用不匹配

c++ - 从函数定义并返回函数?

c++ - 计算数组的不同元素

c++ - 是否可以在 using 声明中引用用户定义的转换模板?

c++ - 了解具有不同签名的继承和函数

C++ 模板类型特征问题