2015-10-13 1 views
8

Les exceptions utilisent le type statique d'un objet à copie-initialise l'objet levé. Par exemple:Pourquoi les objets lancés doivent-ils être copiés-initialisés?

struct foo 
{ 
    foo() = default; 
    foo(const foo&) = delete; 
}; 

int main() 
{ 
    throw foo(); 
} 

Clang++ --std=c++14 que le constructeur se plaint de copie explicitement-supprimé ne peut pas être utilisé. Pourquoi ne peut-il pas être déplacé-initialisé à la place?

+0

Je ne peux plus le supprimer car il a des réponses mais je vote pour fermer comme hors sujet à cause d'une "erreur typographique simple". Mon problème n'était pas aussi trivial que celui-ci, mais j'ai clairement oublié de créer un constructeur de mouvement. – zneak

+0

Grâce à votre question, j'ai appris quelque chose. S'il vous plaît ne votez pas pour le fermer, et par tous les moyens ne le supprime pas !! –

Répondre

9

Il ne peut pas être déplacé construit car le type n'a aucun constructeur de déplacement. Un constructeur de copie supprimé supprime le constructeur de déplacement implicite.

4

Parce que foo(foo&&); est manquant. Par delete en utilisant le constructeur de copie, vous avez également supprimé le constructeur move.

+0

Le constructeur de déplacement n'est pas supprimé, il est simplement absent. –

+0

@JonathanWakely qu'est-ce qui n'est pas 'supprimé, juste manquant'? La suppression du constructeur de copie supprime implicitement le constructeur de déplacement. – SergeyA

+0

@JonathanWakely: Deux sens légèrement différents de "supprimé". Je pense qu'il vaut mieux être explicite ce que l'on peut et ne peut pas faire. Tels que la définition d'un constructeur de mouvement. –

6

Modifier le code à ce qui suit:

struct foo 
{ 
    foo() = default; 
    foo(const foo&) = delete; 
    foo(foo&&) = default; 
}; 

int main() 
{ 
    throw foo(); 
} 

Lire this, la section "constructeur de déplacement Implicitement-déclaré".

3

Le phrasé applicable de la norme (§ [class.copy]/9) ressemble à peu près comme ça (bien, exactement comme celui-ci, au N4296):

Si la définition d'une classe X ne ne pas déclarer explicitement un constructeur de déplacement, on sera implicitement déclaré comme en défaut si et seulement si:

  • X ne dispose pas d'une copie déclarée utilisateur cteur,

[...]

Cela s'applique car définir le ctor de copie comme supprimé signifie toujours que vous avez déclaré le ctor de copie.