コンパイラエラー C2280Compiler Error C2280

'宣言': 削除された関数を参照しようとしています'declaration': attempting to reference a deleted function

コンパイラは、関数を参照しようとしました deletedThe compiler detected an attempt to reference a deleted function. このエラーは、ソースコード内でとして明示的にマークされているメンバー関数の呼び出しによって発生することがあり = deleted ます。This error can be caused by a call to a member function that has been explicitly marked as = deleted in the source code. このエラーは、自動的に宣言され、コンパイラによってマークされる構造体またはクラスの暗黙的な特殊メンバー関数を呼び出すことによって発生することもあり deleted ます。This error can also be caused by a call to an implicit special member function of a struct or class that is automatically declared and marked as deleted by the compiler. コンパイラが自動的にまたは特殊なメンバー関数を生成する場合の詳細について defaultdeleted 、「特殊なメンバー関数」を参照してください。For more information about when the compiler automatically generates default or deleted special member functions, see Special member functions.

例: 明示的に削除された関数Example: Explicitly deleted functions

明示的な関数を呼び出すと、 deleted このエラーが発生します。A call to an explicitly deleted function causes this error. 明示的な deleted メンバー関数は、クラスまたは構造体が使用できないように意図的に設計されていることを意味します。そのため、この問題を解決するには、コードを変更して回避する必要があります。An explicitly deleted member function implies that the class or struct is intentionally designed to prevent its use, so to fix this issue, you should change your code to avoid it.

// C2280_explicit.cpp
// compile with: cl /c /W4 C2280_explicit.cpp
struct A {
    A();
    A(int) = delete;
};

struct B {
    A a1;
    A a2 = A(3); // C2280, calls deleted A::A(int)
    // To fix, remove the call to A(int)
};

void f() {
    B b;    // calls implicit B::B(void)
}

例: 初期化されていないデータメンバーExample: Uninitialized data members

初期化されていない参照型のデータメンバーまたは const データメンバーにより、コンパイラは既定のコンストラクターを暗黙的に宣言し deleted ます。An uninitialized reference type data member or const data member causes the compiler to implicitly declare a deleted default constructor. この問題を解決するには、宣言時にデータメンバーを初期化します。To fix this issue, initialize the data member when it is declared.

// C2280_uninit.cpp
// compile with: cl /c C2280_uninit.cpp
struct A {
    const int i; // uninitialized const-qualified data
    // members or reference type data members cause
    // the implicit default constructor to be deleted.
    // To fix, initialize the value in the declaration:
    // const int i = 42;
} a;    // C2280

例: 参照データメンバーと const データメンバーExample: Reference and const data members

const 参照型または参照型のデータメンバーによって、コンパイラによって deleted コピー代入演算子が宣言されます。A const or reference type data member causes the compiler to declare a deleted copy assignment operator. 初期化されると、これらのメンバーをに割り当てることができないため、単純なコピーや移動は機能しません。Once initialized, these members can't be assigned to, so a simple copy or move can't work. この問題を解決するには、エラーの原因となった割り当て操作を削除するようにロジックを変更することをお勧めします。To fix this issue, we recommend you change your logic to remove the assignment operations that cause the error.

// C2280_ref.cpp
// compile with: cl /c C2280_ref.cpp
extern int k;
struct A {
    A();
    int& ri = k; // a const or reference data member causes
    // implicit copy assignment operator to be deleted.
};

void f() {
    A a1, a2;
    // To fix, consider removing this assignment.
    a2 = a1;    // C2280
}

例: 移動可能な削除の暗黙的なコピーExample: Movable deletes implicit copy

クラスで移動コンストラクターまたは移動代入演算子が宣言されているが、コピーコンストラクターを明示的に宣言していない場合、コンパイラは暗黙的にコピーコンストラクターを宣言し、それをとして定義し deleted ます。If a class declares a move constructor or move assignment operator, but does not explicitly declare a copy constructor, the compiler implicitly declares a copy constructor and defines it as deleted. 同様に、クラスが移動コンストラクターまたは移動代入演算子を宣言していても、コピー代入演算子を明示的に宣言していない場合、コンパイラは暗黙的にコピー代入演算子を宣言し、として定義し deleted ます。Similarly, if a class declares a move constructor or move assignment operator, but does not explicitly declare a copy assignment operator, the compiler implicitly declares a copy assignment operator and defines it as deleted. この問題を解決するには、これらのメンバーを明示的に宣言する必要があります。To fix this issue, you must explicitly declare these members.

との接続にエラー C2280 が表示される場合 unique_ptr 、そのコピーコンストラクターを呼び出そうとしているため、ほぼ確実に deleted 機能します。When you see error C2280 in connection with a unique_ptr, it is almost certainly because you are attempting to invoke its copy constructor, which is a deleted function. 仕様により、を unique_ptr コピーすることはできません。By design, a unique_ptr cannot be copied. 代わりに、移動コンストラクターを使用して所有権を譲渡します。Use a move constructor to transfer ownership instead.

// C2280_move.cpp
// compile with: cl /c C2280_move.cpp
class base
{
public:
    base();
    ~base();
    base(base&&);
    // Move constructor causes copy constructor to be
    // implicitly declared as deleted. To fix this
    // issue, you can explicitly declare a copy constructor:
    // base(base&);
    // If you want the compiler default version, do this:
    // base(base&) = default;
};

void copy(base *p)
{
    base b{*p};  // C2280
}

例: バリアントメンバーと volatile メンバーExample: Variant and volatile members

Visual Studio 2015 Update 2 より前のバージョンのコンパイラは、非準拠で、匿名共用体の既定のコンストラクターとデストラクターが生成されました。Versions of the compiler before Visual Studio 2015 Update 2 were non-conforming and generated default constructors and destructors for anonymous unions. これらは、として暗黙的に宣言されるようになりました deletedThese are now implicitly declared as deleted. また、これらのバージョン default default では、メンバー変数を持つクラスと構造体のコピーコンストラクターと移動コンストラクター、およびコピーおよび移動代入演算子の非準拠の暗黙的な定義も許可されて volatile います。Those versions also allowed non-conforming implicit definition of default copy and move constructors and default copy and move assignment operators in classes and structs that have volatile member variables. コンパイラは、これらを自明なコンストラクターと代入演算子を持つものと見なし、実装を生成しません defaultThe compiler now considers these to have non-trivial constructors and assignment operators, and doesn't generate default implementations. このようなクラスが共用体のメンバー、またはクラス内の無名共用体のメンバーである場合、共用体またはクラスのコピーおよび移動のコンストラクターおよびコピーおよび移動代入演算子は、暗黙的にとして定義され deleted ます。When such a class is a member of a union, or an anonymous union inside of a class, the copy and move constructors and copy and move assignment operators of the union or class are implicitly defined as deleted. この問題を解決するには、必要な特殊なメンバー関数を明示的に宣言する必要があります。To fix this issue, you must explicitly declare the required special member functions.

// C2280_variant.cpp
// compile with: cl /c C2280_variant.cpp
struct A {
    A() = default;
    A(const A&);
};

struct B {
    union {
        A a;
        int i;
    };
    // To fix this issue, declare the required
    // special member functions:
    // B();
    // B(const B& b);
};

int main() {
    B b1;
    B b2(b1);  // C2280
}

例: 間接的な基本メンバーが削除されましたExample: Indirect base members deleted

Visual Studio 2015 Update 2 より前のバージョンでは、派生クラスは間接的に派生した基底クラスの特殊なメンバー関数を呼び出すことができました private virtualVersions of the compiler before Visual Studio 2015 Update 2 were non-conforming and allowed a derived class to call special member functions of indirectly-derived private virtual base classes. コンパイラは、このような呼び出しが行われたときにコンパイラエラー C2280 を発行するようになりました。The compiler now issues compiler error C2280 when such a call is made.

この例では、クラスは top プライベート仮想から間接的に派生 base しています。In this example, class top indirectly derives from private virtual base. 準拠しているコードでは、これにより、のメンバーは base にアクセスできなくなり top ます。型のオブジェクトを top 既定で構築または破棄することはできません。In conforming code, this makes the members of base inaccessible to top; an object of type top can't be default constructed or destroyed. 以前のコンパイラの動作に依存するコードでこの問題を解決するには、派生を使用するように中間クラスを変更する protected virtual か、 top 直接派生を使用するようにクラスを変更します。To fix this issue in code that relied on the old compiler behavior, change the intermediate class to use protected virtual derivation, or change the top class to use direct derivation:

// C2280_indirect.cpp
// compile with: cl /c C2280_indirect.cpp
class base
{
protected:
    base();
    ~base();
};

class middle : private virtual base {};
// Possible fix: Replace line above with:
// class middle : protected virtual base {};
class top : public virtual middle {};    // C4594, C4624
// Another possible fix: use direct derivation:
// class top : public virtual middle, private virtual base {};

void destroy(top *p)
{
    delete p;  // C2280
}