我正在尝试在普通成员函数中使用静态成员。但是编译器报告一些错误。请看一下这段代码
#include <memory>
template<typename T>
class MyClass {
private:
static std::allocator<T> alloc;
T *p;
public:
void assign(T e) {
p = alloc.allocate(1);
alloc.construct(p, e);
}
};
这就是我的用法:
#include 'myclass.h'
int main() {
MyClass<int> cls;
cls.assign(4);
};
然后编译器给出此错误:
/Users/liuziqi/CLionProjects/cpplearning/src/tt.h:17:9: warning: instantiation of variable 'MyClass<int>::alloc' required here, but no definition is available [-Wundefined-var-template]
p = alloc.allocate(1);
^
/Users/liuziqi/CLionProjects/cpplearning/src/main.cpp:49:7: note: in instantiation of member function 'MyClass<int>::assign' requested here
cls.assign(4);
^
/Users/liuziqi/CLionProjects/cpplearning/src/tt.h:13:28: note: forward declaration of template entity is here
static std::allocator<T> alloc;
^
/Users/liuziqi/CLionProjects/cpplearning/src/tt.h:17:9: note: add an explicit instantiation declaration to suppress this warning if 'MyClass<int>::alloc' is explicitly instantiated in another translation unit
p = alloc.allocate(1);
我不知道哪一部分是错误的.....我已经定义了静态成员和任何成员函数都应该能够使用它。此错误与模板有关吗? (我刚刚学习了模板,不确定是否正确使用它。)
答案 0 :(得分:4)
除了回答“如何解决”问题(肯定已经回答过很多次)之外,我还将尝试描述警告所指的内容。
因为MyClass是模板,所以编译器希望模板化类的所有代码在同一文件(myclass.h
)中可用。由于您仅在myclass.h
中声明但未定义alloc,因此编译器认为您犯了一个错误。它不是绝对需要的(因此 warning 而不是 error ),如果在其他位置定义变量,则可以禁用警告,但这几乎肯定是一个错误。
如果您使用的是c ++ 17,处理此问题的最简单方法是将静态成员声明为内联,因此它将在此处定义:
static inline std::allocator<T> alloc;
实时:https://godbolt.org/g/cr1aUP
在C ++ 17之前,您将在myclass.h
中明确定义变量:
template<typename T>
std::allocator<T> MyClass<T>::alloc;