简体   繁体   English

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

[英]Initialization of static template member in CRTP

I try to initialize a static member of a CRTP base class.我尝试初始化 CRTP 基类的静态成员。 The base class holds a static template member of the derived class, while the derived class defines other data members.基类持有派生类的静态模板成员,而派生类定义其他数据成员。 I want to statically initialize this variable.我想静态初始化这个变量。 In code, a minimal example would be the following:在代码中,一个最小的例子如下:

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

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

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

int main()
{}

However, the above does not compile, but gives the error message error: specializing member 'base<derived>::x' requires 'template<>' syntax .但是,上面没有编译,而是给出了错误消息error: specializing member 'base<derived>::x' requires 'template<>' syntax How can I get the static initialization to work?我怎样才能让静态初始化工作?

The correct syntax is:正确的语法是:

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

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

Note that you can't initialize x to a specific integer value, since then your base class won't compile when DERIVED is eg an std::string .请注意,您无法将x初始化为特定的整数值,因为当DERIVED为例如std::string时,您的base类将无法编译。

You probably also want your inheritance to be explicitly public or private.您可能还希望您的继承明确公开或私有。 Ie: IE:

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

Edit: To specialize x and it's initialization for specific types T , you have to specialize base itself.编辑:要专门化x及其对特定类型T的初始化,您必须专门化base本身。 Ie: IE:

class A;

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

// Note missing "template <>" here.
int base<A>::x{ 5 };

class A : public base<A> { };

This seems rather cumbersome, since you need to already forward declare A in this case before declaring the specialization.这看起来相当麻烦,因为在这种情况下,您需要在声明专业化之前预先声明A To me it feels you might want to rethink your design.对我来说,感觉你可能想要重新考虑你的设计。 Is this really required or is there a simpler way to accomplish what you want?这真的是必需的还是有更简单的方法来完成您想要的?

I have found the static initializer trick, which works in the above setting, too.我发现了静态初始化技巧,它也适用于上述设置。 It was described here and here .此处此处对其进行了描述。 In the above context, it would be as follows:在上述情况下,它将如下所示:

#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";
}

The above output the value 1 .以上输出值1

Note: this works with C++17.注意:这适用于 C++17。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM