2010-09-27 22 views
4
class Foo { 
    Foo(int val) { /* Do some initialization */ } 
    Foo() { /* Do nothing */ } 
}; 
union Bar { 
    Foo foo; 
}; 

Ce code génère cet erreur:Stuff classe constructeurs défini utilisateur une union

erreur C2620: membre 'Titi :: foo de syndicat Bar' dispose constructeur personnalisée ou non- constructeur par défaut trivial

Je comprends pourquoi vous lancer cette erreur si le constructeur a effectivement fait quelque chose, mais le constructeur ici ne prend aucun paramètre et ne fait rien. Y a-t-il un moyen de transformer cette classe en syndicat? J'ai dû faire tout le chemin pour faire char foo[sizeof(Foo)] et je voudrais une solution plus propre.

Répondre

1

Les spécialistes des normes répondront probablement à cette question plus précisément que moi, mais si je me souviens bien, les membres du syndicat doivent être de type POD.

Utilisez boost::variant si vous souhaitez utiliser des classes non-POD dans une union.

6

A l'origine de cette question:

Initializing a union with a non-trivial constructor:

De C++ 03, 9.5 syndicats, pg 162

Un syndicat peut avoir des fonctions membres (y compris les constructeurs et destructeurs), mais pas virtuel (10.3) fonctions. Une union ne doit pas avoir de classes de base. Une union ne doit pas être utilisée comme classe de base.Un objet d'une classe avec un constructeur non-trivial (12.1), un constructeur de copie non-trivial (12.8), un destructeur non-trivial (12.4), ou un non-trivial L'opérateur d'affectation de copie (13.5.3, 12.8) ne peut pas être membre d'une union, pas plus qu'un tableau de tels objets.

Votre classe est donc interdite d'être membre de l'union.

0

Si votre classe a un constructeur, destructeur ou constructeur de copie défini par l'utilisateur ou un opérateur d'affectation, il ne peut pas être à l'intérieur d'une Union.

3

Ceci n'est pas autorisé dans la norme C++ 03.

Si des objets avec des constructeurs par défaut définis par l'utilisateur étaient autorisés dans une union, le compilateur ne pouvait pas décider quel constructeur utiliser, car tous se référaient au même emplacement de mémoire. Ainsi, les objets avec des constructeurs définis par l'utilisateur ne sont pas autorisés dans les unions.

Le compilateur ignore le fait que votre constructeur ne fait rien, car il peut être défini ailleurs que dans l'union.

Vous pourriez sortir avec C++ 0x constructor() = default;

+0

C'est dommage ... si je n'utilise que « Foo() = défaut » cela fonctionne, mais si j'ajouter un autre constructeur avec la valeur par défaut explicite qu'il se plaint à nouveau. – Chris

+0

constructor() = par défaut résolu cela pour moi dans VS 2013, n'ont pas encore testé GCC ou Xcode. – eodabash