C ++定义静态成员的正确方法是什么

时间:2018-07-30 00:25:34

标签: c++

我正在尝试在普通成员函数中使用静态成员。但是编译器报告一些错误。请看一下这段代码

#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);

我不知道哪一部分是错误的.....我已经定义了静态成员和任何成员函数都应该能够使用它。此错误与模板有关吗? (我刚刚学习了模板,不确定是否正确使用它。)

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;

实时:https://godbolt.org/g/2Znqst