错误 C2079:"堆栈命名空间::堆栈节点:<T>:值"使用未定义的类

error C2079: 'stackNameSpace::StackNode<T>::value' uses undefined class

本文关键字:堆栈 未定义 lt 命名空间 C2079 节点 错误 gt      更新时间:2023-10-16

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'"

我不知道为什么它有错误。有人能帮帮我吗?

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>代替。对于具有类型参数T的模板定义,该类型必须使用普通的T而不是class T来引用。

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

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

这里的StackNodePtr不依赖于模板参数T。相反,它是一个指向固定类型StackNode<::stackNameSpace::T>的指针,并且top->value将是与Stack的模板形参无关的不完整类型class T

如果您使用Stack<int>并在这样的堆栈中使用top->value实例化任何东西,您将看到您显示的错误。

顺便说一句:另一个不相关的问题是模板的定义(包括类模板的成员函数)必须在模板实例化时可见。通常,这意味着不应该将模板成员定义放入单独编译的cpp文件中。相反,它们应该在头文件中,该头文件包含在使用模板的任何地方。

虽然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来自build。在解决方案资源管理器>属性>从构建中排除>是。