11

構築できない型を作りたいとしましょう (理由は聞かないでください)。

struct Impossible
{

私はこのようにすることができます:

    Impossible() = delete;
    // disable automatically generated constructors, don't declare any others
    Impossible(const Impossible&) = delete;
    // I suppose this is redundant with nothing to copy

またはこのように:

    Impossible(...) = delete;
    // explicitly disable all constructors

またはこのように:

    template<typename... Ts>
    Impossible(Ts...) = delete;
    // explicitly disable all constructors, template version
};

コンストラクタだけでなく、どの関数についても同じことを尋ねることができると思います。

どちらを選択しても違いはありますか? 構文に関しては、2 番目のオプションが気に入っていると思います。しかし、エラーメッセージのテキスト以外で違いを検出できる状況はありますか?

4

3 に答える 3

8

最初のもので十分です-コンパイラーによってコンストラクターが生成されることはなく、最も重要なこととして、それは慣用的なものです。

于 2013-01-03T11:18:42.547 に答える
7

たとえば、次のような違いがあります。

#include <type_traits>

struct Unconstructible
{
    Unconstructible() = delete;
};

static_assert( !std::is_default_constructible<Unconstructible>::value, "not default constructible" );
static_assert( std::is_copy_constructible<Unconstructible>::value, "copyable" );

このオブジェクトを構築することはできないため、実際にはオブジェクトのコピーを作成することもできませんが、言語とライブラリの型の特徴によると、暗黙的に宣言されたコピー コンストラクターがあるため、技術的には CopyConstructible です。

同様に、Impossible(...)orImpossible(Ts&&...)フォームには、暗黙的に宣言されたコピー コンストラクターがまだあります。

一方、このようにすると、次のようになります。

#include <type_traits>

struct Unconstructible
{
    Unconstructible(const Unconstructible&) = delete;
};

static_assert( !std::is_default_constructible<Unconstructible>::value, "not default constructible" );
static_assert( !std::is_copy_constructible<Unconstructible>::value, "not copyable" );

ユーザー宣言コンストラクターが存在すると、既定のコンストラクターの暗黙的な宣言が抑制されるため、クラスは DefaultConstructible でも CopyConstructible でもありません。


NB、最後の例は、おそらく、コピー不可および移動不可のものを含む、あらゆるImpossible(Ts&&...)タイプに一致するはずです。

于 2013-01-03T15:33:05.133 に答える
5

このクラスのインスタンスを作成することはできません。

struct Impossible
{
    Impossible() = delete;
};

copy-constructor(またはmove-constructor)の問題は発生しないため、削除する必要はありません。オブジェクトは構築できないため存在できないため、コピーや移動は問題ありません。

于 2013-01-03T11:21:36.487 に答える