具有嵌套类的模板类

时间:2013-10-31 11:51:59

标签: c++ templates nested-class

1 #include <iostream>
2 using namespace std;
3 template<typename T>
4 class Top {
5 public:
6     class Sub {
7         protected:
8             T age;
9     };
10     class Derived : public Sub {
11         public:
12             void printAge() {
13                 cout << age << endl;
14             }
15     };  
16 };
17 int main()
18 {
19     return 0;
20 }

当我编译代码时,我收到以下错误:

test.cpp: In member function ‘void Top<T>::Derived::printAge()’:
test.cpp:13:25: error: ‘age’ was not declared in this scope
             cout << age << endl;

但如果它不是模板,那就没问题了。 我很高兴收到你的答案。

3 个答案:

答案 0 :(得分:1)

派生中的

年龄是模板内的名称。标准定义了两种名称:

  • 依赖:依赖于模板参数但不依赖于模板参数的名称 在模板中声明。
  • 非依赖:不依赖于模板参数的名称,以及模板本身的名称和在其中声明的名称。

在第cout << age << endl行,age是一个非依赖名称,应在模板定义时解析。此时,编译器仍然不知道年龄是多少,因为Top :: sub可以/稍后可以专用。因此它不会在基类中查找名称,而只是在封闭范围内。由于封闭范围内没有年龄,编译器会抱怨。

添加此 - &gt;或者Top :: on age使其依赖,因此查找规则会发生变化。现在,在模板的实例化时解决了年龄问题,编译器完全理解了基类,并且可以正确地解析名称。

答案 1 :(得分:0)

class Top<T>::Derived : public Top<T>::Sub

是另一种思考Derived继承的方法。如果考虑到这种方式,则Sub中的变量似乎取决于类型T。当您使用依赖于template参数类型的变量时,您通常需要明确(Sub::age)或明确它是成员(this->age)。

现在在这种情况下,虽然基数似乎依赖于T,但您可以证明基数是什么。然而,这最终取决于标准中的一些精细措辞,以及编译器对该极端情况的实现(成功与否)。

因此,要解决您的问题,请在这种情况下使用this->age

答案 2 :(得分:0)

age取决于模板类型参数,因此其评估是模板即时阶段。正如您在this thread中看到的那样,继承和模板不能很好地工作。在第一个(声明)阶段检查派生类上成员的使用,并且(如上所述),在第二阶段声明(“解析”)成员。所以编译器没有声明这些内容。

解决这个问题的一种方法是通过this指针访问memeber,强制编译器检查基类。