错误C2079:'stackNameSpace :: StackNode <t> :: value'使用未定义的类</t>

时间:2013-04-19 21:21:51

标签: c++

Stack.h的接口

#include "stdafx.h"

//use linkedlist to implement the stack 
//which is different from using the array to implement the stack


#ifndef STACK_H
#define STACK_H

using namespace std;

namespace stackNameSpace {

template<class T>
struct StackNode {
    T value;
    T min_value; //current local min value 
    StackNode* next;
};

typedef StackNode<class T>* StackNodePtr;

template<class T>
class Stack {
private:
      StackNodePtr top;

public:

Stack();

Stack(const Stack& a_stack);

~Stack();

bool empty() const;

T pop();


void push(T the_value);

T getMin();

};

} //end of namespace

#endif

stack.h的实现

#include "stdafx.h"

//use linkedlist to implement the stack 
//which is different from using the array to implement the stack


#ifndef STACK_CPP
#define STACK_CPP
#include <iostream>
#include <cstdlib>
#include "Stack.h"

using namespace std;

namespace stackNameSpace {


template<class T>
Stack<T>::Stack() : top(NULL)  //here should be Stack<T> instead of Stack
{}

template<class T>
Stack<T>::Stack(const Stack& a_stack) {
    if (a_stack.top == NULL) {
        return NULL;
    }
    else {
        StackNodePtr currentOld = a_stack.top;
        //construct the top of the new stack
        StackNodePtr currentNew = new StackNode<class T>;//the struct 
        currentNew->value = currentOld->value;
        currentNew->min_value = currentOld->min_value;
        top = currentNew;

        //contruct the rest node in the stack
        currentOld = currentOld->next;
        while (currentOld != NULL) {
            currentNew->next = new StackNode<class T>;
            currentNew = currentNew->next;
            currentNew->value = currentOld->value;
            currentNew->min_value = currentOld->min_value;

            currentOld = currentOld->next;
        }
        currentOld->next = NULL;

    }
}

template<class T>
Stack<T>::~Stack() {
    T data;
    while (!empty()) {
        data = pop();
    }
}

template<class T>
bool Stack<T>::empty() const {
    return (top == NULL);
}

template<class T>
T Stack<T>::pop() {

    if (empty()) {
        cout << "Error: popping an empty stack.\n";
        exit(1);
    }

    T result = top->value;

    StackNodePtr temp = new StackNode<class T>;
    temp = top;
    top = top->next;

    delete temp;

    return result;

}

template<class T>
void push(T the_value) {

    StackNodePtr temp = new StackNode<class T>;
    temp->value = the_value;

    temp->min_value = min(the_value, getMin());//This is Much better

    //temp->min_value = top->min_value; //This is NOT secure, since top may be NULL

    temp->next = top; //update the top node
    top = temp;

}

template<class T>
T getMin() {
    if (top == NULL) 
        return INT_MAX;
    else {
        return top->min_value;
    }
}

} //end of namespace 

#endif

使用Stack类的函数

#include "stdafx.h"

#include <iostream>
#include "Stack.h" //this is not the <stack>, which is STL


//using namespace std; //NOTE: this must be wrong! because can not use multiple namespace at the same time
using namespace stackNameSpace;
using std::cout;
using std::endl;

int main() {

    Stack<int> sWithMin;

    sWithMin.push(5);
    cout<< sWithMin.getMin() << endl;
    sWithMin.push(4);
    cout<< sWithMin.getMin() << endl;
    sWithMin.push(5);
    cout<< sWithMin.getMin() << endl;
    sWithMin.push(3);
    cout<< sWithMin.getMin() << endl;
    sWithMin.push(6);
    cout<< sWithMin.getMin() << endl;



    return 0;

}

当我编译项目时,我在main()中得到一个错误“错误C2079:'stackNameSpace :: StackNode :: value'使用未定义的类'stackNameSpace :: T'”

我无法弄清楚它有错误的原因。有人可以帮帮我吗?

2 个答案:

答案 0 :(得分:2)

namespace stackNameSpace {

template<class T>
struct StackNode {
    T value;
    T min_value; //current local min value 
    StackNode* next;
};

因此StackNode是一个依赖于类型参数T的模板。

typedef StackNode<class T>* StackNodePtr;

这不是模板定义的一部分,class T指的是名为T.的类

(实际上class T总是引用一个名为T的类,但构造template <class T>除外,它可以被template <typename T>替换。带有类型参数{{1}的模板定义必须使用普通T,而不是T来引用该类型。)

由于您还没有声明一个名为class T的类,T定义会在周围的命名空间范围内隐式声明一个不完整的类类型(即不完整的类类型为StackNodePtr)。

::stackNameSpace::T

现在,此处template<class T> class Stack { private: StackNodePtr top; 不依赖于模板参数StackNodePtr。相反,它是指向固定类型T的指针,而StackNode<::stackNameSpace::T>将是与top->value的模板参数无关的不完整类型class T

如果你使用Stack并在这样的堆栈中使用Stack<int>实例化任何内容,你会看到你显示的错误。

BTW:另一个不相关的问题是模板的定义(包括类模板的成员函数)必须在实例化模板时可见。通常,这意味着您不应将模板成员定义放入单独编译的top->value文件中。相反,它们应该位于使用模板的头文件中。

答案 1 :(得分:1)

虽然JoergB正确地指出了您发布的代码的问题,但我想对他在答案的最后部分解释的内容有所了解。

在Visual Studio中使用模板时,我会确保该类的标头和实现属于单个编译单元。尝试将Stack.cpp重命名为Stack.inl并将其包含在Stack.h的末尾

void push(T the_value);

T getMin();

};

} //end of namespace

#include "Stack.inl"

#endif

请务必从构建中排除Stack.inl。在解决方案资源管理器中右键单击它&gt;属性&gt;从构建中排除&gt;是。