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_ptr
je 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
}