2010-02-02 9 views
6

Ich habe die folgende Klassenhierarchie:C++ Compiler Fehler mit CRTP

template <typename T> 
class base 
{ 
public: 
    void f() {} 
}; 

class class_a : public base<class_a> {}; 

class class_b : public base<class_b>, 
       public class_a 
{ 
    using base<class_b>::f; 
}; 

int main() 
{ 
    class_b b; 
    b.f(); 
    return 0; 
} 

COMEU und Intel C++ v11 Anspruch, alles ist gut, aber GCC (4.4.1) und VC++ 2008 scheinen (http://codepad.org/KQPDsqSp) zu beklagen, zB :

g++ -pedantic -Wall -o test test.cpp 
test.cpp: In function ‘int main()’: 
test.cpp:5: error: ‘void base<T>::f() [with T = class_b]’ is inaccessible 
test.cpp:14: error: within this context 

ich der Code glauben und es ist gebildet, jedoch könnte ich falsch sein, ich hoffe, dass jemand aus der sO C++ Gemeinschaft könnte einen Einblick in dieses Thema geben.

Hinweis: Das Hinzufügen von "public" vor der using-Anweisung in class_b behebt das Problem für gcc und VS. Sollte der Accessor-Abschnitt der Klasse, in der die using-Direktive angewendet wird, den Ableitungsmodus (public, private) der Basisklasse überschreiben?

Kurz gesagt ist diese

  • einen Compiler-Fehler - wenn ja, welche Compiler GCC, VS oder COMEU, Intel
  • Ist der obige Code gut ausgebildet?
  • Überschreibt der Accessor-Abschnitt, in dem eine using-Direktive aufgerufen wird, den Ableitungsmodus der Base?

Antwort

3

Was Sie hier tun, ist die Lösung eine Zweideutigkeit durch das Symbol in die Klassen importieren privaten Namespace. Daher ist es Methode, die Sichtbarkeit zu ändern und zu ändern. Sie können nicht zwei Funktionen mit dem gleichen Prototyp sowohl privat als auch öffentlich haben, daher ist das f jetzt privat.

Zumindest GCC glaubt, dass using should be able to change the visibility einer Funktion.

Vage Referenzen jedoch in GCC bug database gefunden, zeigen, dass die Verwendung in der Tat nicht durch den Anwendungsbereich betroffen sein sollte.

Am wichtigsten ist, eine direkte Antwort (C++ Standard-'03 - 7.3.3/15)

Die Alias ​​durch die using-Deklaration erstellt hat die übliche Zugänglichkeit für ein Mitglied Deklaration.

Daher sind die Antworten wäre:

  • es ist ein Fehler in Comeau
  • nein, wird der Code nicht gut ausgebildet ist, zumindest C++ 03-weise (kann nichts damit verbundenen finden in C++ 0x N3000)
  • ja, können Sie Zugriffsbereich
+0

Nichts in einem privaten Namespace oder Umfang ändern ist. und die using-Direktive berücksichtigt nicht den Accessor-Teil der Klasse, in der sie aufgerufen wird - jedoch das Hinzufügen von public, bevor die using-Direktive das Problem löst. Ich glaube in diesem Fall gcc und VS sind schuld, meinst du nicht? –

+2

@darid, in dem obigen Link sehen Sie, dass es zumindest in GCCs Fall so geändert wurde, wie es jetzt explizit ist. –

+0

@Kornel: das ist eine ausgezeichnete Antwort, ich möchte hinzufügen, dass ich es mit dem Intel C++ Compiler versucht habe und es mag es wie Comeau tut.Ich frage mich, ob es ein Parser-Interface-Problem ist, Intel und Comeau bekommen ihre von EDG, aber auch MS für VSC++, was die Dinge nur noch mehr verwirrt. –