CRTP中静态模板成员的初始化

时间:2020-10-29 09:32:14

标签: c++ static crtp

我尝试初始化CRTP基类的静态成员。基类包含派生类的静态模板成员,而派生类定义其他数据成员。我想静态初始化此变量。在代码中,一个最小的示例如下:

template<typename DERIVED>
class base {
    public:
        static DERIVED x;   
};

class derived : public base<derived>
{
    public:
        int a;   
};

int base<derived>::x {0};

int main()
{}

但是,以上代码没有编译,但是给出了错误消息error: specializing member 'base<derived>::x' requires 'template<>' syntax。 如何使静态初始化起作用?

2 个答案:

答案 0 :(得分:0)

正确的语法是:

template <class T>
class base {
  public:
    static T x;   
};

template <class T>
T base<T>::x{};

请注意,您无法将x初始化为特定的整数值,因为那样的话base不会在DERIVED时编译您的std::string类。 class derived : public base<derived> { public: int a; };

您可能还希望您的继承显式为公共或私有。即:

x

编辑:要专门化T并将其初始化为特定类型base,您必须专门化class A; template <> class base<A> { public: static int x; }; // Note missing "template <>" here. int base<A>::x{ 5 }; class A : public base<A> { }; 本身。即:

A

这似乎很麻烦,因为在这种情况下,您需要先声明re.findall,然后再声明专业化。对我来说,您可能想重新考虑您的设计。这真的是必需的,还是有一种更简单的方法来实现您想要的?

答案 1 :(得分:0)

我已经找到了静态初始值设定项技巧,也可以在上述设置中使用。描述了herehere。在上述情况下,将如下所示:

#include <iostream>

template<typename DERIVED>
class base {
    public:
        static inline DERIVED x;   
};

class derived : public base<derived>
{
    public:
        int a;
        
        struct static_initializer {
            static_initializer()
            {
                derived::x.a = 1;
            }
        };
         
        static inline static_initializer static_initializer_;        
};

int main()
{
    std::cout << derived::x.a << "\n";
}

上面的输出值为1

注意:这适用于C ++ 17。