175 votes

erreur : utilisation d'une fonction supprimée

J'ai travaillé sur un code C++ écrit par un ami et j'ai obtenu l'erreur suivante, que je n'avais jamais vue auparavant, lors de la compilation avec 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’

Edit : Cela vient d'une partie du code utilisant boost MSM : Page Web de Boost

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

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

4 votes

Et le code que vous compilez ?

0 votes

Je me demandais plutôt ce que signifiait cette erreur ? Dois-je afficher le code pour cela aussi ?

1 votes

gcc.gnu.org/bugzilla/show_bug.cgi?id=47417 Cela pourrait aider. Utilisez-vous aussi Boost ?

218voto

Jerry Coffin Points 237758

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

class X {
    const int x;
};

Desde X::x est const il doit être initialisé -- mais un ctor par défaut ne l'initialiserait pas normalement (parce que c'est un type POD). Par conséquent, pour obtenir un ctor par défaut, vous devez en définir un vous-même (et il doit initialiser le type POD). 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 utile de noter que ces deux options désactivent également la création implicite d'un opérateur d'affectation, pour la même raison. L'opérateur d'affectation implicite effectue normalement une affectation en fonction des membres, 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 affecté. Pour que l'affectation fonctionne, vous devez écrire votre propre opérateur d'affectation.

C'est pourquoi un const Le membre doit généralement être statique -- quand vous faites une affectation, vous ne pouvez pas affecter le membre const de toute façon. Dans un cas typique, toutes vos instances auront la même valeur, alors autant partager l'accès à une seule variable au lieu d'avoir plusieurs copies d'une variable qui auront toutes la même valeur.

Il est possible, bien sûr, de créer des instances avec des valeurs différentes -- vous (par exemple) passez une valeur lorsque vous créez l'objet, donc deux objets différents peuvent avoir deux valeurs différentes. Si, toutefois, vous essayez de faire quelque chose comme les échanger, le membre const conservera sa valeur originale au lieu d'être échangé.

0 votes

@Jeffry Coffin : Le message d'erreur réel a été posté comme une modification, le message d'erreur initial posté était seulement C++ error: use of deleted function

1 votes

@Als : Désolé, j'aurais probablement dû être explicite sur le fait que je n'avais pas l'intention de le faire comme une insulte ou quoi que ce soit de cet ordre, juste que ce qui était actuellement disponible rendait évident que ces réponses n'étaient pas bonnes.

0 votes

Je suppose que vous pourriez être en mesure de m'aider à résoudre mon problème ici, s'il vous plaît : stackoverflow.com/questions/23349524/

11voto

Alok Save Points 115848

Vous utilisez une fonction, qui est marquée comme étant deleted .
Eg :

int doSomething( int ) = delete;

Le =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 utilise cette fonction.

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

Pour en savoir plus sur cette nouvelle fonctionnalité introduite dans C++0x, consultez este dehors.

10 votes

Par curiosité, quand est-ce que faire quelque chose comme ça serait utile ?

0 votes

@Peter : pour éviter les conversions implicites.

10 votes

En fait, il est écrit "implicitement supprimé parce que ..." l'exemple ci-dessus serait explicite.

4voto

Bo Persson Points 42821

Gcc 4.6 supporte une nouvelle fonctionnalité de fonctions supprimées, où vous pouvez écrire

hdealt() = delete;

pour désactiver le constructeur par défaut.

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

2voto

jarmond Points 636

Dans la norme C++0x actuelle, vous pouvez explicitement désactiver les constructeurs par défaut à l'aide de la syntaxe de suppression, par exemple

MyClass() = delete;

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

0 votes

Gcc 4.6 is the first version to support this syntax Je suppose que cela explique pourquoi je ne l'ai jamais vu auparavant, car je n'ai commencé à utiliser gcc4.6 que récemment.

2 votes

J'utilise cette syntaxe avec GCC 4.5 depuis des années. Je veux dire des jours.

0 votes

Ah, je devais penser aux ctors délégués qui sont dans GCC 4.6.

1voto

TonyK Points 8604

Tu peux essayer ça, s'il te plaît ? Je n'ai pas gcc-4.6

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

Il devrait donner un message d'erreur similaire si les personnes ici présentes sont correctes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X