C2280 fordítási hiba

"deklaráció": törölt függvényre való hivatkozás

Megjegyzések

A fordító egy függvényre való hivatkozási deleted kísérletet észlelt. Ezt a hibát a forráskódban explicit módon megjelölt = deleted tagfüggvény hívása okozhatja. Ezt a hibát az is okozhatja, ha egy szerkezet vagy osztály implicit speciális tagfüggvényét hívja meg, amelyet a fordító automatikusan deklarál és jelöl deleted meg. További információ arról, hogy mikor jön létre default automatikusan a fordító vagy deleted a speciális tagfüggvények: Speciális tagfüggvények.

Példa: Explicit módon törölt függvények

Ezt a hibát egy explicit módon deleted működő függvény hívása okozza. A kifejezetten deleted tagfüggvények azt jelentik, hogy az osztály vagy a szerkezet szándékosan úgy van kialakítva, hogy megakadályozza annak használatát, ezért a probléma megoldásához módosítania kell a kódot, hogy elkerülje azt.

// 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)
}

Példa: Nem inicializált adattagok

Egy nem inicializált referenciatípus adattagja vagy const adattagja miatt a fordító implicit módon deklarál egy alapértelmezett konstruktort deleted . A probléma megoldásához inicializálja az adattagot a deklaráláskor.

// 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

Példa: Referencia- és konstansadat-tagok

Egy const vagy referenciatípus adattagja miatt a fordító deklarál egy másolás-hozzárendelési operátort deleted . Az inicializálás után ezek a tagok nem rendelhetők hozzá, így egy egyszerű másolás vagy áthelyezés nem működik. A probléma megoldásához javasoljuk, hogy módosítsa a logikát a hibát okozó hozzárendelési műveletek eltávolításához.

// 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
}

Példa: Ingó törli az implicit másolatot

Ha egy osztály áthelyezési konstruktort vagy áthelyezés-hozzárendelési operátort deklarál, de nem deklarál explicit módon egy példánykonstruktort, a fordító implicit módon deklarál egy példánykonstruktort, és a következőképpen definiálja azt deleted. Hasonlóképpen, ha egy osztály áthelyezési konstruktort vagy áthelyezés-hozzárendelési operátort deklarál, de nem deklarál explicit módon másolás-hozzárendelési operátort, a fordító implicit módon deklarál egy másolás-hozzárendelési operátort, és definiálja azt .deleted A probléma megoldásához kifejezetten deklarálnia kell ezeket a tagokat.

Ha c2280-ás hibát lát egy unique_ptradottval kapcsolatban, az szinte biztosan azért van, mert megkísérli meghívni a másolási konstruktort, amely egy deleted függvény. Tervezés szerint a unique_ptr program nem másolható. Ehelyett áthelyezési konstruktor használatával ruházhatja át a tulajdonjogot.

// 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
}

Példa: Variant és volatilis tagok

A Visual Studio 2015 Update 2 előtti fordítóverziók nem feleltek meg a követelményeknek, és alapértelmezett konstruktorokat és destruktorokat hoztak létre a névtelen egyesítésekhez. Ezek most implicit módon deklarálva lesznek deleted. Ezek a verziók lehetővé tették a másolási és áthelyezési konstruktorok nem megfelelő implicit definícióját default , valamint default a hozzárendelési operátorok másolását és áthelyezését olyan osztályokban és szerkezetekben, amelyek tagváltozókkal rendelkeznek volatile . A fordító most úgy véli, hogy ezek nem triviális konstruktorokkal és hozzárendelési operátorokkal rendelkeznek, és nem hoznak létre default implementációkat. Ha egy ilyen osztály tagja egy uniónak, vagy egy osztályon belüli névtelen uniónak, akkor az egyesítők másolása és áthelyezése, valamint az egyesítő vagy osztály hozzárendelési operátorainak másolása és áthelyezése implicit módon a következőképpen deletedvan definiálva: . A probléma megoldásához explicit módon deklarálnia kell a szükséges speciális tagfüggvényeket.

// 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
}

Példa: Közvetett alaptagok törölve

A Visual Studio 2015 Update 2 előtti fordítóverziók nem feleltek meg, és lehetővé tették, hogy egy származtatott osztály meghívja a közvetetten származtatott private virtual alaposztályok speciális tagfüggvényét. A fordító mostantól c2280-ás fordítói hibát ad ki ilyen hívás esetén.

Ebben a példában az osztály top közvetetten magán virtuálisból baseszármazik. A megfelelő kódban a tagok base elérhetetlenné topteszik azokat; egy ilyen típusú top objektum nem hozható létre vagy semmisíthető meg alapértelmezés szerint. Ha a régi fordítói viselkedésre támaszkodó kódban szeretné megoldani a problémát, módosítsa a köztes osztályt a származtatás használatára protected virtual , vagy módosítsa az osztályt top a közvetlen származtatás használatára:

// 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
}