簡體   English   中英

CRTP中靜態模板成員的初始化

[英]Initialization of static template member in 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 我怎樣才能讓靜態初始化工作?

正確的語法是:

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

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

請注意,您無法將x初始化為特定的整數值,因為當DERIVED為例如std::string時,您的base類將無法編譯。

您可能還希望您的繼承明確公開或私有。 IE:

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

編輯:要專門化x及其對特定類型T的初始化,您必須專門化base本身。 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> { };

這看起來相當麻煩,因為在這種情況下,您需要在聲明專業化之前預先聲明A 對我來說,感覺你可能想要重新考慮你的設計。 這真的是必需的還是有更簡單的方法來完成您想要的?

我發現了靜態初始化技巧,它也適用於上述設置。 此處此處對其進行了描述。 在上述情況下,它將如下所示:

#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。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM