2013-11-14 10 views
7

Ist dieser Code C++ (11) gültig?Geschachtelte Klasse durch Mehrfachvererbung ausgeblendet

struct Base { 
    template <typename> 
    struct nested; 
}; 
struct Derived1 : Base { }; 
struct Derived2 : Base { }; 
struct Derived3 : Derived1, Derived2 { }; 

typedef Derived3::nested<int> xxx; 

Was ich weiß

Der obige Code nicht mit kompilieren:

  • von Apple LLVM 5.0 (Klirren-500.2.75)
  • Clang 3,4

Aber es kompiliert erfolgreich mit:

  • gcc 4.9.0 20.131.110 (experimentell)
  • gcc 4,8

Auch wenn ich die nested Typ in einen Nicht-Template-Typ ändern, dh

struct Base { 
    struct nested; 
}; 
... 
typedef Derived3::nested xxx; 

dann funktioniert es mit den oben genannten Compilern. ändert nichts

[Bearbeiten] Ändern der nested Template-Struktur zu einer Vorlage alias auch;

template <typename> struct dependent { struct type; }; 
struct Base { 
    template <typename T> 
    using nested = typename dependent<T>::type; 
}; 

erzeugt die gleichen Ergebnisse mit den oben genannten Compiler. [end bearbeiten]

Von N3242 §10.1 [class.mi]

Eine Klasse kann eine indirekte Basisklasse mehr als einmal sein und kann eine direkte und eine indirekte Basisklasse sein. Es gibt begrenzte Dinge, die mit solch einer Klasse gemacht werden können. Auf die nicht statischen Datenelemente und Elementfunktionen der direkten Basisklasse kann nicht im Bereich der abgeleiteten Klasse verwiesen werden. Auf die statischen Elemente, Aufzählungen und Typen kann jedoch eindeutig Bezug genommen werden.

ich denke, es bedeutet, dass der Code gültig sein sollte, aber ich bin mir nicht sicher.

+0

Ich suchte nach dem [bug report] (https://bugs.llvm.org/show_bug.cgi?id=17929) (id 17929), das vom OP gefüllt wurde, da der Bug (?) Immer noch in clang 5.0 auftaucht .1. Leider gab es keine Antworten. – Caninonos

Antwort

0

Es ist in Ordnung, GCC ist entweder rechts/hilfreicher (es zum Standard klebt sehr stark)

Es kann nicht sehen, warum die Definition mehrdeutig sein würde, weil Sie über eine Art Rede ist kein Mitglied, und Typ sind gleich, wenn ihre Namen gleich sind in C++ (Namen sind einige verstümmelte Form von Typen beteiligt und so weiter)

Nachtrag:

Es wäre falsch, wenn „verschachtelt“ und „verschachtelt“ in der anderen Basis waren anders. Es ist eine Struktur, nicht ein typedef oder verwenden (die sind im Geltungsbereich)

GCC wird weinen, wenn etwas mehrdeutig ist, versuchen Sie mit -pedantic, wenn Sie es Hündin machen wollen, auch wenn es nicht ist. Ich sehe keinen Grund, warum dies abgelehnt werden sollte, auch wenn GCC nur permissiv ist.

+0

Ich bin mir nicht sicher, ob ich Ihren Nachtrag verstehe. Meinst du, dass der Code mehrdeutig sein könnte, wenn "verschachtelt" zum Beispiel ein C++ 11-Template-Alias ​​anstelle einer Template-Struktur wäre? –

+0

@LouisDionne ja, weil sie verschiedene Dinge alias können. Sie werden beim Parsing wie Member behandelt, da die gleichen Regeln gelten. Das Diamond-Problem hebt sich mit dem Alias, den Sie verwenden wollten, auf. –

+0

@LouisDionne habe ich die Frage beantwortet? .... –