13

実行時に値をラップするだけのクラスを考えてみましょう:

template <typename Type>
class NonConstValue 
{
    public:
        NonConstValue(const Type& val) : _value(val) {;}
        Type get() const {return _value;}
        void set(const Type& val) const {_value = val;}
    protected:
        Type _value;
};

そしてその constexpr バージョン:

template <typename Type>
class ConstValue 
{
    public:
        constexpr ConstValue(const Type& val) : _value(val) {;}
        constexpr Type get() const {return _value;}
    protected:
        const Type _value;
};

質問 1: constexpr バージョンが正しい方法で設計されていることを確認できますか?

質問 2: 両方のクラスを、構築または実行時に構築でき、実行時またはコンパイル時に値を持つことValueができる単一のクラスにどのように混合しますか?constexprget()

編集: 質問 3:ファイルでget()定義されている場合、関数の正しい宣言ではない場合にインライン化する場合は? それは...ですか.cppget()constexpr

constexpr inline Type get();

また

inline constexpr Type get()

または、他の何か ?

4

2 に答える 2

28

潜在的な定数式constexprである関数のそれぞれに指定子を追加するだけです。

template <typename Type>
class Value 
{
public:
    constexpr Value(Type const& val) : _value(val) {}
    constexpr Type const& get() const {return _value;}
    void set(Type const& val) {_value = val;}
protected:
    Type _value;
};

constまたは非 constタイプでテンプレートをインスタンス化することで実行できるため、const バージョンと非 const バージョンは必要ありません。Value

constexpr非 constexprバージョンは必要ありません。これは、constexpr潜在的な定数式を意味し、式が定数式なるかどうかはその引数に依存します。式がコンパイル時に評価されるかどうかは、コンテキストと実装に依存します。

于 2013-01-18T00:59:56.487 に答える
2

クラスは正しく設計されていますが、コンストラクターの名前のタイプミス (ではなくconstexprである必要があります) を除きます。しかし、それはただのタイプミスだと確信しています。ConstValueValue

バージョンのインスタンスは、constexprコンパイル時オブジェクトと実行時オブジェクトの両方として使用できます。

template <typename Type>
class ConstValue
{
    public:
        constexpr ConstValue(const Type& val) : _value(val) {;}
        constexpr Type get() const {return _value;}
    protected:
        const Type _value;
};

int main(int argc, char* argv[])
{
    int x[ConstValue<int>(3).get()];
}
于 2013-01-18T01:00:42.393 に答える