fout: gebruik van verwijderde functie

Ik heb aan wat C++-code gewerkt die een vriend heeft geschreven en ik krijg de volgende foutmelding die ik nog nooit eerder heb gezien bij het compileren met gcc4.6:

error: use of deleted function
‘GameFSM_<std::array<C, 2ul> >::hdealt::hdealt()’ is implicitly deleted because the default definition would be ill-formed:
uninitialized non-static const member ‘const h_t FlopPokerGameFSM_<std::array<C, 2ul> >::hdealt::h’

Bewerken: dit komt van een deel van de code die boost MSM gebruikt: Webpagina boosten

Edit2: Er wordt nergens in de broncode = delete()gebruikt.

Wat betekent deze fout in het algemeen? Waar moet ik op letten als dit type fout optreedt?


Antwoord 1, autoriteit 100%

De foutmelding zegt duidelijk dat de standaardconstructor implicietis verwijderd. Er staat zelfs waarom: de klasse bevat een niet-statische, const-variabele, die niet zou worden geïnitialiseerd door de standaardctor.

class X {
    const int x;
};

Aangezien X::xconstis, moet het worden geïnitialiseerd — maar een standaard ctor zou het normaal gesproken niet initialiseren (omdat het een POD-type is). Om een standaard ctor te krijgen, moet je er dus zelf een definiëren (en het moet xinitialiseren). Je kunt dezelfde situatie krijgen met een lid dat een referentie is:

class X { 
    whatever &x;
};

Het is waarschijnlijk de moeite waard om op te merken dat allebei ook impliciete creatie van een opdrachtoperator zullen uitschakelen, voor in wezen dezelfde reden. De impliciete toewijzingsexploitant doet normaal gesproken leden-wijze toewijzing, maar met een const-lid- of referentielid, kan het dat niet doen omdat het lid niet kan worden toegewezen. Om opdrachtwerk te doen, moet u uw eigen toewijzingsoperator schrijven.

Dit is de reden waarom een ​​const-lid typisch statisch is – wanneer u een opdracht doet, kunt u toch niet het constant toewijzen. In een typisch geval zullen al uw gevallen dezelfde waarde hebben, zodat ze net zo goed toegang hebben tot een enkele variabele in plaats van veel kopieën van een variabele te hebben die allemaal dezelfde waarde heeft.

Het is natuurlijk mogelijk om gevallen met verschillende waarden te creëren – u (bijvoorbeeld) passeert een waarde wanneer u het object maakt, zodat twee verschillende objecten twee verschillende waarden kunnen hebben. Als u echter probeert iets te doen als het ruilen van hen, behoudt het COND-lid de oorspronkelijke waarde in plaats van geruild te worden.


Antwoord 2, Autoriteit 6%

U gebruikt een functie, die is gemarkeerd als deleted.
Bijv.:

int doSomething( int ) = delete;

De = Delete is een nieuwe functie van C++ 0x. Het betekent dat de compiler onmiddellijk moet stoppen met het samenstellen en klagen “Deze functie wordt verwijderd” zodra de gebruiker een dergelijke functie gebruikt.

Als u deze fout ziet, moet u de functieaangifte controleren voor =delete.

Om meer te weten te komen over deze nieuwe functie geïntroduceerd in C++ 0x, controleer dit uit.


Antwoord 3, Autoriteit 2%

gcc 4.6 ondersteunt een nieuwe functie van verwijderde functies, waar u kunt schrijven

hdealt() = delete;

om de standaardconstructor uit te schakelen.

Hier heeft de compiler duidelijk gezien dat er geen standaardconstructor kan worden gegenereerd, en =deleteheeft het voor je gedaan.


Antwoord 4

Ik ben deze fout tegengekomen toen ik overnam van een abstracte klasse en niet alle pure virtuele methoden in mijn subklasse implementeerde.


Antwoord 5

In de huidige C++0x-standaard kun je standaardconstructors expliciet uitschakelen met de delete-syntaxis, bijvoorbeeld

MyClass() = delete;

Gcc 4.6 is de eerste versie die deze syntaxis ondersteunt, dus misschien is dat het probleem…


Antwoord 6

Overschakelen van gcc 4.6 naar gcc 4.8 loste dit voor mij op.

Other episodes