Sdílet prostřednictvím


Chyba kompilátoru C2280

"deklarace": pokus o odkaz na odstraněnou funkci

Kompilátor zjistil pokus o odkaz deleted na funkci. Příčinou této chyby může být volání členské funkce, která byla explicitně označena jako = deleted ve zdrojovém kódu. Tato chyba může být způsobena také voláním implicitní speciální členské funkce struktury nebo třídy, která je automaticky deklarována a označena jako deleted kompilátor. Další informace o tom, kdy kompilátor automaticky generuje default nebo speciální členské funkce, naleznete v tématu Speciální členské funkcedeleted.

Příklad: Explicitně odstraněné funkce

Volání explicitní deleted funkce způsobí tuto chybu. Explicitní deleted členová funkce znamená, že třída nebo struktura jsou záměrně navrženy tak, aby se zabránilo jeho použití, takže pokud chcete tento problém vyřešit, měli byste změnit kód, aby se tomu zabránilo.

// 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říklad: Neinicializované datové členy

Neinicializovaný datový člen nebo const datový člen referenčního typu způsobí, že kompilátor implicitně deklaruje deleted výchozí konstruktor. Chcete-li tento problém vyřešit, inicializace datového členu při deklaraci.

// 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říklad: Referenční a const datové členy

const Datový člen referenčního typu způsobí, že kompilátor deklaruje deleted operátor přiřazení kopírování. Po inicializaci nelze těmto členům přiřadit, takže jednoduchá kopie nebo přesunutí nebudou fungovat. Pokud chcete tento problém vyřešit, doporučujeme změnit logiku tak, abyste odebrali operace přiřazení, které způsobily chybu.

// 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říklad: Pohyblivé odstranění implicitní kopie

Pokud třída deklaruje konstruktor přesunutí nebo operátor přiřazení přiřazení, ale explicitně deklaruje konstruktor kopírování, kompilátor implicitně deklaruje konstruktor kopírování a definuje jej jako deleted. Podobně, pokud třída deklaruje konstruktor přesunutí nebo operátor přiřazení, ale explicitně deklaruje operátor přiřazení kopírování, kompilátor implicitně deklaruje operátor přiřazení kopírování a definuje jej jako deleted. Chcete-li tento problém vyřešit, musíte explicitně deklarovat tyto členy.

Když se zobrazí chyba C2280 v připojení k , unique_ptrje téměř jistě, protože se pokoušíte vyvolat jeho konstruktor kopírování, což je deleted funkce. unique_ptr Záměrně nelze kopírovat. K převodu vlastnictví použijte konstruktor přesunutí.

// 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říklad: Variantní a nestálé členy

Verze kompilátoru před sadou Visual Studio 2015 Update 2 nebyly vygenerované a vygenerovaly výchozí konstruktory a destruktory pro anonymní sjednocení. Nyní jsou implicitně deklarovány jako deleted. Tyto verze také umožňovaly nevyhovující implicitní definici konstruktorů default kopírování a přesunutí a default kopírování a přesouvání přiřazení ve třídách a strukturách, které mají volatile členské proměnné. Kompilátor nyní považuje tyto konstruktory a operátory přiřazení, které nejsou triviální, a negeneruje default implementace. Je-li taková třída členem sjednocení nebo anonymní sjednocení uvnitř třídy, kopírování a přesunutí konstruktory a kopírovat a přesunout operátory přiřazení sjednocení nebo třídy jsou implicitně definovány jako deleted. Pokud chcete tento problém vyřešit, musíte explicitně deklarovat požadované speciální členské funkce.

// 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říklad: Odstraněné nepřímé základní členy

Verze kompilátoru před sadou Visual Studio 2015 Update 2 nebyly v souladu a umožňovaly odvozené třídě volat speciální členské funkce nepřímo odvozených private virtual základních tříd. Kompilátor teď vydává chybu kompilátoru C2280, když se takové volání provede.

V tomto příkladu třída top nepřímo odvozena od privátní virtuální base. V souladu s kódem to způsobí, že členové base jsou nepřístupní top; objekt typu top nemůže být vytvořen nebo zničen. Pokud chcete tento problém vyřešit v kódu, který spoléhal na staré chování kompilátoru, změňte zprostředkující třídu tak, aby používala protected virtual odvození, nebo změňte top třídu tak, aby používala přímé odvození:

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