2015-10-06 2 views
5

classes de base virtuelles sont initialisés dans la classe la plus dérivée, donc je suppose que héritant le constructeur de la classe de base devrait fonctionner aussi bien:constructeurs Hériter des classes de base virtuelles

struct base { 
    base(int) {} 
}; 

struct derived: virtual base { 
    using base::base; 
}; 

derived d(0); 

Cependant, ce ne peut pas compiler avec GCC 5.2.0, qui essaie de trouver base::base(), mais fonctionne bien avec Clang 3.6.2. Est-ce un bug dans GCC?

+3

pertinent: http://stackoverflow.com/questions/2126522/c-virtual-inheritance – SingerOfTheFall

Répondre

5

Ce bug est gcc 58751 "[C++ 11] Héritant constructeurs ne fonctionnent pas correctement avec l'héritage virtuel" (aka: 63339 "à l'aide des constructeurs" à partir de bases virtuelles sont implicitement supprimées «): Dans le document N2540, il déclare

que::

De la description 58751

Habituellement, hériter des définitions de constructeur pour les classes avec des bases virtuelles sera mal formé, à moins que la base virtuelle ne prenne en charge l'initialisation par défaut, ou que la base virtuelle soit une base directe et nommée base forwarded-to. De même, tous les membres de données et autres bases directes doivent prendre en charge l'initialisation par défaut, ou toute tentative d'utilisation d'un constructeur héritant sera mal formée. Remarque: mal formé lorsqu'il est utilisé, non déclaré.

Par conséquent, le cas des bases virtuelles est explicitement considéré par le comité et devrait donc être mis en œuvre.

Solution empruntée au rapport de bogue:

struct base { 
    base() = default; // <--- add this 
    base(int) {} 
}; 

Selon le rapport de bogue, dans ce cas, le constructeur base::base(int) est appelé par le constructeur généré implicitement derived::derived(int).

J'ai vérifié que your code ne compile pas. Mais this le fait et il appelle le constructeur base::base(int).

+0

Bien sûr, cela ne fonctionne toujours pas si 'base' ne peut pas être construit par défaut ... Il semble donc que la seule façon Autour de ceci est de re-définir manuellement les constructeurs dans toutes les classes dérivées. –