Argumentabhängige Suche anhand der Basis einer Vorlagenklasse

8

Ich habe eine Template-Klasse NB::B<T> , die von einer Nicht-Template-Klasse NA::A in einem Namespace abgeleitet ist. act<T> ist eine Vorlagenfunktion, die add_ref function für eine Instanz ihres Vorlagenarguments aufruft. Insbesondere act<NB::B<int>> möchte add_ref im Namensraum der Basis von NB::B mithilfe von ADL finden. Das vollständige Beispiel folgt:

%Vor%

Dies kompiliert in gcc (4.7.0). Und in Comeau online. Jedoch schlägt clang (3.1) fehl:

%Vor%

Gleichzeitig lautet der Standard:

  

3.4.2 / 2 ...

     

- Wenn T eine Vorlagen-ID ist, sind die zugehörigen Namespaces und Klassen der Namespace, in dem die Vorlage definiert ist. für Mitgliedervorlagen die Klasse der Mitgliedervorlage; die Namespaces und Klassen, die den Typen der Vorlagenargumente zugeordnet sind, die für die Parameter des Vorlagentyps bereitgestellt werden (mit Ausnahme der Vorlagenparameter); die Namespaces, in denen Vorlagenvorlagenargumente definiert sind; und die Klassen, in denen alle als Vorlagevorlagenargumente verwendeten Elementvorlagen definiert sind.

Überraschenderweise werden Vorlagenbasen nicht als Pfade zu zugeordneten Namespaces aufgelistet. Das Verhalten von clang scheint also korrekt zu sein. Und Comeau und gcc akzeptieren falsches Programm.

Gleichzeitig gibt 3.4.2/3 an, dass using in den Namespaces des Arguments keine Auswirkung haben:

  

Wenn ein assoziierter Namespace berücksichtigt wird, entspricht die Suche der Suche, die ausgeführt wird, wenn der zugeordnete Namespace als Qualifikationsmerkmal (3.4.3.2) verwendet wird, mit Ausnahme von:

     

- Alle using-Direktiven im zugehörigen Namespace werden ignoriert.

Aber wenn ich die using NA::add_ref -Zeile auskommentiere clang ist glücklich, den Test zu kompilieren.

Um mein Beispiel in praktische Perspektive zu bringen, können Sie denken, dass act eine Methode von boost::intrusive_ptr war, add_ref(A*) war intrusive_ptr_add_ref(CBase*) und B war eine Vorlage, abgeleitet von der Basis CBase .

In diesem Zusammenhang habe ich einige Fragen:

  1. Habe ich Recht, dass clang 's korrekt ist, mein Testprogramm abzulehnen, und gcc und Comeau folgen nicht dem Standard?

  2. Gibt es einen Grund, warum der Standard ein solches unpraktisches Verhalten spezifiziert (die Vorlagenklassenbasen als assoziierte Namespaces nicht zulassen)?

  3. Ist clang falsch akzeptiert mein Testprogramm mit der using NA::add_ref -Direktive aufgrund von 3.4.2/3 ?

  4. Soll ich einen Fehler melden? :)

P.S. Ich habe die Sprachkompatibilität FAQ gelesen und dort keine Antwort gefunden.

    
Nicht Verstehen 23.07.2012, 19:25
quelle

1 Antwort

6

Von n3337, was im Grunde C ++ 11 mit kleineren redaktionellen Änderungen ist, lautet die 3.4.2 / 2:

  

Für jeden Argumenttyp T im Funktionsaufruf [...] Die Mengen von   Namespaces und Klassen werden folgendermaßen bestimmt: [...]

     
  • Wenn T ein Klassentyp ist (einschließlich Unionen), sind die ihm zugeordneten Klassen: die Klasse selbst; die Klasse, der es angehört, falls vorhanden; und seine direkten und indirekten Basisklassen . Die zugehörigen Namespaces sind die Namespaces, deren zugehörige Klassen Mitglieder sind. Außerdem , wenn T eine Klassenvorlagenspezialisierung ist, ...
  •   

Und es geht dann mit dem im Grunde genommen gleichen Zitat weiter, das Sie in der Frage gepostet haben. Der wichtige Unterschied ist hier außerdem , was bedeutet, dass die Liste, die Sie angegeben haben (und ich weggelassen habe), zusätzlich zu den bereits erwähnten Namespaces existiert und die Namespaces enthält, deren Basisklasse ein Member ist .

  1. Gcc und comeau haben Recht, und c ++ ++ ist falsch bei der Ablehnung des Codes.

  2. & lt; gilt nicht & gt;

  3. Clang ++ ist falsch bei der Ablehnung ohne using NA::add_ref .

  4. Ja, Sie sollten wahrscheinlich einen Fehler melden. Es scheint, dass es bereits gemeldet und behoben wurde.

David Rodríguez - dribeas 23.07.2012, 19:37
quelle