web-dev-qa-db-fra.com

erreur: utilisation de la fonction supprimée

J'ai travaillé sur du code C++ écrit par un ami et le message d'erreur suivant que je n'ai jamais vu lors de la compilation avec gcc4.6 est le suivant:

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’

Edit: Cela provient d'une partie du code utilisant boost MSM: page Web Boost

Edit2: Il n'y a pas de = delete() utilisée dans le code source.

De manière générale, que signifie cette erreur? Que devrais-je rechercher lorsque ce type d'erreur se produit?

99
shuttle87

Le message d'erreur indique clairement que le constructeur par défaut a été supprimé implicitement. Il dit même pourquoi: la classe contient une variable const non statique, qui ne serait pas initialisée par le ctor par défaut.

class X {
    const int x;
};

Puisque X::x est const, il doit être initialisé - mais un ctor par défaut ne l'initialisera pas normalement (car il s'agit d'un type de POD). Par conséquent, pour obtenir un ctor par défaut, vous devez en définir un vous-même (et il doit initialiser x). Vous pouvez obtenir le même genre de situation avec un membre qui est une référence:

class X { 
    whatever &x;
};

Il est probablement intéressant de noter que ces deux fonctionnalités vont également désactiver la création implicite d'un opérateur d'affectation, essentiellement pour les mêmes raisons. L'opérateur d'affectation implicite effectue normalement une affectation par membre, mais avec un membre const ou un membre de référence, il ne peut pas le faire car le membre ne peut pas être assigné. Pour que le travail d’affectation fonctionne, vous devez écrire votre propre opérateur d’affectation.

C'est pourquoi un membre const devrait généralement être statique - lorsque vous effectuez une affectation, vous ne pouvez pas affecter le membre const de toute façon. Dans un cas typique, toutes vos instances vont avoir la même valeur. Par conséquent, elles peuvent également partager l'accès à une seule variable au lieu de disposer d'un grand nombre de copies d'une variable qui auront toutes la même valeur.

Bien sûr, il est possible de créer des instances avec des valeurs différentes, par exemple: vous transmettez une valeur lors de la création de l'objet, de sorte que deux objets différents peuvent avoir deux valeurs différentes. Si, toutefois, vous essayez de les remplacer, le membre const conservera sa valeur d'origine au lieu d'être échangé.

148
Jerry Coffin

Vous utilisez une fonction qui est marquée comme deleted.
Par exemple:

int doSomething( int ) = delete;

The = delete est une nouvelle fonctionnalité de C++ 0x. Cela signifie que le compilateur doit immédiatement arrêter de compiler et se plaindre "cette fonction est supprimée" une fois que l'utilisateur l'utilise.

Si vous voyez cette erreur, vous devriez vérifier la déclaration de fonction pour =delete.

Pour en savoir plus sur cette nouvelle fonctionnalité introduite dans C++ 0x, cochez this out.

8
Alok Save

gcc 4.6 prend en charge une nouvelle fonctionnalité des fonctions supprimées, où vous pouvez écrire

hdealt() = delete;

désactiver le constructeur par défaut.

Ici, le compilateur a bien vu qu'un constructeur par défaut ne peut pas être généré, et =delete 'le fait pour vous.

2
Bo Persson

Passer de gcc 4.6 à gcc 4.8 a résolu ce problème pour moi.

1
Michael Bosworth

Pouvez-vous essayer ceci, s'il vous plaît? Je n'ai pas gcc-4.6

class C
  {
public:
  const int x ;
  } ;
int main()
  {
  C c ;
  }

Un message d'erreur similaire devrait apparaître si les personnes présentes sont correctes.

1
TonyK

Dans la norme C++ 0x actuelle, vous pouvez explicitement désactiver les constructeurs par défaut avec la syntaxe de suppression, par exemple.

MyClass() = delete;

Gcc 4.6 est la première version à supporter cette syntaxe, alors peut-être que c'est le problème ...

1
jarmond

J'ai rencontré cette erreur lors de l'héritage d'une classe abstraite sans implémenter toutes les méthodes virtuelles pures de ma sous-classe.

0
Christopher