16

次のコードを検討してください。

#include <iostream>

class Test
{
    public:
        constexpr Test(const int x) : _x(x) {}
        constexpr int get() const {return _x;}
        ~Test() {} // HERE
    protected:
        const int _x;
};

int main()
{
    static constexpr Test test(5);
    return 0;
}

この行を削除すると、コードは正常にコンパイルされますが、空のデストラクタを定義すると、それが非リテラルHEREであるというコンパイル エラーが発生します。Test

空のデストラクタとまったくないデストラクタの違いはなぜですか?

編集:別の関連する質問:空のデストラクタとリテラルデストラクタが異なる場合、保護されたリテラルデストラクタを定義する方法は?

4

2 に答える 2

20

n3376からの引用

7.1.5/9

オブジェクト宣言で使用される constexpr 指定子は、オブジェクトを const として宣言します。そのようなオブジェクトはリテラル型を持ち、初期化されます。コンストラクター呼び出しによって初期化される場合、その呼び出しは定数式でなければなりません

3.9/10

次の場合、型はリテラル型です。

それは簡単なデストラクタを持っています...

12.4/5

ユーザーが提供しない場合、および次の場合、デストラクタは自明です。

— デストラクタは仮想ではありません。

— そのクラスのすべての直接基底クラスには、自明なデストラクタがあります。

— クラス型 (またはその配列) であるそのクラスのすべての非静的データ メンバーについて、そのような各クラスには自明なデストラクタがあります。

それ以外の場合、デストラクタは自明ではありません。

clang diagnostic は実際にはより有益です:

error: constexpr variable cannot have non-literal type 'const C'

'C' is not literal because it has a user-provided destructor
于 2013-01-10T10:39:36.067 に答える