2010-09-14 4 views
5

Ich habe festgestellt, dass dieser seltsame Fall von etwas Code (unten) unter Visual Studio 2008 nicht kompiliert und einen "Fehler C2872: Ambiguity" erzeugt: mehrdeutiges Symbol“auf der Leitung 12.VS2008 (+?) Compiler-Fehler mit Vorlagenfunktionen und 'using namespace'

die mit namespace RequiredNamespace in der letzten Zeile behebt den Fehler entfernen, aber ich würde erwarten, dass using namespace am Ende einer Datei setzen sollte keine Auswirkung. Es stützt sich auch auf AnotherFunction ist eine Vorlage-Funktion, so erwarte ich, dass der Compiler die Vorlagenfunktionen im falschen Bereich generiert, oder die Liste der Namespaces nicht zurückgesetzt wird, die zuvor verwendet wird.

Der gleiche Code kompiliert unter GCC.

Beide Compiler scheinen den Code für TemplatedFunction nach der using namespace Namespace Definition zu generieren, zumindest so weit ich kann sagen, indem Fehler eingeführt und auf die Reihenfolge, die sie ausgegeben werden.

namespace Ambiguity 
{ 
    class cSomeClass 
    { 
    }; 

    template<class T> 
    void TemplatedFunction(T a) 
    { 
     // this is where the error occurs, the compiler thinks Ambiguity 
     // might refer to the class in RequiredNamespace below 
     Ambiguity::cSomeClass(); 
    } 
} 

namespace RequiredNamespace 
{ 
    // without a namespace around this class, the Ambiguity class 
    // and namespace collide 
    class Ambiguity 
    { 
    }; 
} 

int main() 
{ 
    // to force the templated function to be generated 
    Ambiguity::TemplatedFunction(4); 
} 

// removing this removes the error, but it shouldn't really do anything 
using namespace RequiredNamespace; 

Offensichtlich ist dies ein hergestelltes Beispiel, aber das Original aus einem realen Fall extrahiert wird, wo die using namespace in einer automatisch generierten Datei von 3rd-Party-Code erzeugt wird.

Ist das ein Fehler im Compiler?

+1

ist es mir oder ist das ein wirklich schwer zu lesendes Beispiel, mit diesen bestimmten Bezeichnern? –

+0

Preet - es ist nicht nur du. –

+0

Wie kann ich es einfacher machen?Ich nehme an, dass ein Teil des Problems darin besteht, dass das Problem nicht auftritt, wenn Benennungskonventionen befolgt werden - wenn Sie beispielsweise Ihren Klassen c vorangestellt hätten, hätten Sie keine Klasse namens Ambiguity. Ich habe es ein wenig optimiert. – eAi

Antwort

2

Ich glaube, es ist ein Fehler, pro 7.3.4 Abs 1 des C++ 03-Standard:

Eine using-Direktive legt fest, dass die Namen in der benannten Namespace können im Rahmen verwendet werden, in denen Die using-Direktive erscheint nach der using-Direktive.

Ihre End-of-File-Deklaration sollte also keine Wirkung haben.

5

Ich stimme zu, dass es sich um einen Fehler handelt, aber einige Einblicke in das, was vor sich geht, können generiert werden, indem Sie die Ihrer Datei entsprechende Assembly-Liste generieren (verwenden Sie die/Fa-Option von cl.exe).

Also, kommentieren Sie die using-Deklaration, generieren Sie die .asm-Datei und öffnen Sie sie in einem Texteditor. Scannen Sie die Datei und Sie können sehen, dass sich die Instanziierung der Vorlage am Ende der Datei befindet (sie beginnt mit [email protected]@[email protected]@[email protected] PROC) und sie wird unter der Assembly für die Hauptfunktion generiert (beginnt mit _main PROC). Die Fehlermeldung besagt "siehe Verweis auf Funktionsvorlageninstanziierung", bezieht sich also auf die Instanziierung der Vorlagenfunktion, und die Assemblyliste macht deutlich, dass diese Instanziierung am Ende der Datei steht.

Bearbeiten Sie nun den Code, um die Vorlagenfunktion durch NonTemplatedFunction(int a) zu ersetzen, und erstellen Sie eine Assembly-Liste. Zeigen Sie den Assembly-Eintrag an und Sie werden sehen, dass der für NonTemplatedFunction(int a) generierte Assembly-Code über _main PROC angezeigt wird.

Was bedeutet das ganze Geschwätz? Wenn der Visual Studio 2008-Compiler Ihre Vorlagen in tatsächlichen Code umwandelt, fügt er nach der Verwendung der Deklaration effektiv Code an das Ende Ihrer Datei an. Ihre using-Deklaration bedeutet, dass die Namen im automatisch generierten Code "mehrdeutig" sind. Der Prozess, den gcc verwendet, um Vorlagen zu instanziieren, vermeidet dieses Problem offensichtlich.

+0

+1: Wenn Sie es in eine nicht vorlagenbasierte Funktion geändert haben, wird sich Intellisense beschweren, aber die Datei wird kompiliert. – Puppy

Verwandte Themen