错误 C2079:"堆栈命名空间::堆栈节点:<T>:值"使用未定义的类
error C2079: 'stackNameSpace::StackNode<T>::value' uses undefined class
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。在解决方案资源管理器>属性>从构建中排除>是。
- 编译C++时未定义的引用
- vscode g++链路故障:体系结构x86_64的未定义符号
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 不知道某个东西是否被忽略会引入未定义的行为吗
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 未定义的引用在哪里
- 编译时的 CImg 库返回对"__imp_SetDIBitsToDevice"的未定义引用
- 未定义的卫生化无法检测到简单的堆栈外误差
- 未定义对调用堆栈库的引用出现问题
- 尝试实现堆栈时C++未定义的引用
- C++11 Lambda闭包通过引用涉及一个堆栈变量,该变量离开作用域是允许的,但得到了未定义的行为
- 是否可以为 CString 返回堆栈对象以及为什么 /GR 导致未定义的行为dynamic_cast
- 体系结构x86_64的未定义符号:构建堆栈
- 从堆栈地址形成指针范围是未定义的行为吗
- 如何在这个无锁堆栈函数中防止未定义的行为和ABA问题
- 错误 C2079:"堆栈命名空间::堆栈节点:<T>:值"使用未定义的类
- 小对象堆栈存储,严格混叠规则和未定义行为
- 如果局部堆栈变量是未定义的行为,为什么编译器会发出有关返回对局部堆栈变量的引用的警告
- 分配过大的堆栈结构是未定义的行为吗