簡體   English   中英

clang vs gcc CRTP:constexpr變量不能有非文字類型

[英]clang vs gcc CRTP: constexpr variable cannot have non-literal type

我這里有一個CRTP模板類:

template <typename S>
class Base
{
    public:
    constexpr static S NOT_SET{0};
};

struct Derived : public Base<Derived>
{
};

Clang(5.0.0)不接受這個:

5 : <source>:5:24: error: constexpr variable cannot have non-literal type 'const Derived'
    constexpr static S NOT_SET{0};
                       ^
8 : <source>:8:25: note: in instantiation of template class 'Base<Derived>' requested here
struct Derived : public Base<Derived>
                        ^
5 : <source>:5:24: note: incomplete type 'const Derived' is not a literal type
    constexpr static S NOT_SET{0};
                       ^
8 : <source>:8:8: note: definition of 'Derived' is not complete until the closing '}'
struct Derived : public Base<Derived>
       ^
1 error generated.
Compiler exited with result code 1

但gcc(在4.9.2和6.2上測試)接受它就好了。

如何在clang中這樣做呢?

當您嘗試在類模板Base使用Derived不是完整類型,因此您無法以這種方式實際使用它。 那是因為必須完整的類型才能聲明該類型的變量。 沒辦法解決它。
總而言之,類型在結束時完成} (以及與您的情況無關的其他異常,例如在其成員函數內)。
這就是標准所說的( 工作草案 ):

在類說明符的結束時,類被視為完全定義的對象類型(或完整類型)。
在類成員規范中,該類在函數體,默認參數,noexcept-specifiers和默認成員初始化器(包括嵌套類中的這類事物)中被視為完整。
否則,它在其自己的類成員規范中被視為不完整。

因此clang是對的,錯誤或多或少相同。


正如評論中所提到的,存在一種解決它的方法。 只要派生類型是(讓我說) constexpr可構造 ,你可以在基類中定義一個constexpr函數,它返回你未設置的版本(無論它意味着什么)。

暫無
暫無

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

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