2016-04-10 11 views
2

これは無知な質問ですが、私はまだconstexpr指定子を使用する方法と使用方法について私の頭を包んでいます。 (msvc 14でコンパイル)。 私は任意のオブジェクトを "constexprオブジェクト"にラップすることができる単純な基本クラスに取り組んでいます。それは次のようになります。派生クラスの関数でConstexpr指定子を使用する

template<typename T> 
class basic_const { 
public: 

    explicit constexpr basic_const(const T& value) : data_(value) { } 

    template <typename...Args> 
    constexpr basic_const(Args&&...args) : data_(T(std::forward<Args>(args)...)) { } 

    virtual ~basic_const() = default; 

    constexpr const T& data() const noexcept { return data_; } 

private: 
    T data_; 
}; 

すべてが予想通り、私は成功した(明らかに)constexprとしての資格できる任意の型のオブジェクトを作成することができます動作します。

ここに問題があります:
このクラスから継承しようとすると、私は追加のconstexprメンバ関数を実装することはできませんが、私はできます。

class str_const : public basic_const<const char*> 
{ 
public: 

    template <std::size_t N> 
    constexpr str_const(const char(&str)[N]) : 
     basic_const(str), sz_(N) {} 
    ... 
    constexpr std::size_t size() const noexcept{ return sz_; } // error here 
    ... 
public: 
    std::size_t sz_; 
}; 

iが派生クラスでconstexprのメンバ関数を作成することができます。次のコードは、私が実装していますconstexpr文字列クラスのためにあるのですか?私があまりにも達成しようとしています何のようだ

答えて

2

問題は、あなたがyour answerに書いたものではないようです。問題は、仮想デストラクタ(つまり、non-trivial destructor)が存在するため、包含クラスがliteral typeではないことです。 GCCは(私を強調する)吐き出す:

error: enclosing class of constexpr non-static member function 'std::size_t str_const::size() const' is not a literal type

Live example with the error

はデストラクタからvirtual修飾子を削除し、それが動作します。

Live example working

メンバ変数のための追加constのための必要はありません。

EDIT

打ち鳴らすしかしcompiles your code just fine ...これはバグですかしら。これが実際にはvirtual destructor is non-trivialのような密接なバグであることに気付きました。だから、clangはそのままあなたのコードをコンパイルするべきではありません。

+0

ありがとうございました。 –

+0

@NowhereManよろしくお願いします。私はまだclangバグを埋めるための最小限の例を考え出しています。 – vsoftco

+0

constexprメンバ関数がリテラル型に対してのみ宣言できるという制限は、C++ 11の制限であり、CWG1684でC++ 11から遡って削除され、C++ 14から完全に削除されました。 GCCはここで間違っています、Clangは正しいので、この答えは間違っています。 ; - D(EDIT:変更された特定の表現は[dcl.constexpr]/8にありました; "*その関数がメンバであるクラスはリテラル型でなければなりません*"が削除されました) – ildjarn

0

は完全に許容され、派生クラスのメンバ変数はconstにベースと派生クラスの両方の変数を変更し、const宣言されていなかった問題を修正しました。

関連する問題