簡體   English   中英

由於模板基類,從不完整類型初始化靜態constexpr

[英]Initializing a static constexpr from an incomplete type because of a template base class

我有一個模板基類,期望子類將自己作為模板參數傳遞。

看起來有點像這樣:

template<typename T>
struct Base {
    constexpr Base(int x) : m_x(x) {}
private:
    int m_x;
};

struct Derived : public Base<Derived>
{
    static const Derived LIFE;
    constexpr Derived(int x) : Base(x) {}
};

const Derived Derived::LIFE = Derived(42);

編譯並按預期工作。 但現在我想讓Derived :: LIFE成為一個constexpr。 這甚至可能嗎?

我不能只將const限定符更改為constexpr,因為constexpr需要在其聲明中初始化:

test.cpp:10:28: error: constexpr static data member ‘LIFE’ must have an initializer
   static constexpr Derived LIFE;

我無法在那里初始化它,因為Derived是一個不完整的類型:

test.cpp:10:45: error: invalid use of incomplete type ‘struct Derived’
   static constexpr Derived LIFE = Derived(42);

我意識到如果Derived是一個完整的類型,這個問題就會消失,但在這個特殊情況下,由於與這個問題無關的原因,我非常依賴於自引用的模板化基類。

如果我正確地理解了這個答案中的最后一段,聽起來至少有一些關於改變未來某個時候處理不完整類型的方式的討論,但這對我現在沒有幫助。

是否有人知道在我的上述代碼中推遲LIFE初始化的某種技巧?

您只需將constexpr添加到LIFE的定義中:

constexpr Derived Derived::LIFE = Derived(42);

直到最近GCC還有一個錯誤,它拒絕了這一點; 你需要使用Clang或GCC 4.9。

我認為你應該使用延遲初始化 實際上Derived仍然是不完整的類型; 因為編譯器還不知道它的大小。

所以代碼應該是:

struct Derived : public Base<Derived>
{
    constexpr Derived(int x) : Base(x) {}

    static constexpr Derived getLIFE()
    {
        return Derived(34);
    }
};

編輯:使用此代碼段可以重現相同的incomplete type行為:

struct MyStruct
{
    static constexpr int x = sizeof(MyStruct);
};

暫無
暫無

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

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