从类模板派生类

时间:2015-03-13 11:24:49

标签: c++ templates

我是C ++的新手。在我的学习阶段,我遇到了以下问题。 我正在尝试从类模板stack派生一个类Queue。 编译器在stack

的构造函数中抛出错误
..\src\TrainingDay2.cpp:44:3: error: 'b' was not declared in this scope
   b=a;

请帮助找出根本原因。

#include <iostream>
using std::cout;
using std::endl;

template<class T> class Queue //Base class
{
private:
    T ArrQueue[20];
protected:
    T* a;
    T* b;
public:

    Queue() { cout<<"QUEUE CONST "<<  endl; }
    void push(T x);
    void pop(void);
};


template <class T>
class stack :public Queue<T> // Derived class
{
public:
    stack():Queue<T>() {
        b=a;
    }
    void pop() {
        b--;
    }
};


int main()
{
    stack<int> S;
    return 0;
}

3 个答案:

答案 0 :(得分:2)

因为基类是一个模板,其实例化取决于派生类的模板参数,并且您试图命名基类的成员,所以要编写两阶段查找{{1 }},而不是this->b

(并且不需要默认的构造函数调用。)

b

live demo

欢迎使用C ++ ...:P


  

stack() { this->b = this->a; } void pop() { this->b--; } 在类或类模板的定义中,如果基类依赖于模板参数,则在非限定名称查找期间不会检查基类范围。类模板或成员的定义点,或者在类模板或成员的实例化过程中。 [..]

答案 1 :(得分:2)

原因是在模板内部,适用两阶段名称查找规则:

  • 在定义(=解析)模板时,会查找(=已解析)不依赖于模板参数的名称。

  • 在实例化模板时(当您提供模板参数时)会查找依赖于模板参数的名称。

  • 仅在实例化时的名称查找期间搜索依赖于模板参数的基类。

这种两阶段查找的原因是,在知道模板参数之前,编译器无法知道基类(或其他相关构造)的定义是什么。请记住,模板专业化存在。

您需要以某种方式告诉编译器名称b是依赖的。你基本上有三种方法可以做到这一点:

  1. 使用this->作为名称的前缀;因为您在类模板中,所有成员都隐式依赖模板参数:

    this->b = a;
    
  2. 使用名称的完全限定条件。这将使模板参数的依赖性显式:

    Queue<T>::b = a;
    
  3. using声明放入您的类,以通知编译器该名称来自依赖基类:

    template <class T>
    class stack :public Queue<T> // Derived class
    {
    protected:
        using Queue<T>::b;
    
    public:
        stack():Queue<T>()
        {
            b=a;
        }
         void pop()
        {
            b--;
        }
    };
    

答案 2 :(得分:0)

  

在模板定义中,非限定名称将不再找到依赖库的成员(由C ++标准中的[temp.dep] / 3指定)。例如,   您必须使名称依赖,例如通过在它们前面加上这个 - >;

gcc-problem-using-a-member-of-a-base-class-that-depends-on-a-template-argument

是的,它可以在VS中有效。