2013-03-17 10 views
12

Ich stieß auf ein Problem portiert einige Code zu MSVC, die mich verwirrt. Soweit ich weiß, sollte der Code legal sein, und Clang kompiliert es einfach gut.Warum kann MSVC diese Vorlagenfunktion nicht kompilieren?

ich es verengt haben bis auf die folgenden:

enum E { 
    x 
}; 

template <typename T> 
struct traits { 
    static const E val = x; 
}; 

template <E e> 
struct S { 
    S(){}; 
}; 

template <typename T> 
S<traits<T>::val> foo(T t); 

int main() { 
    char c = 0; 
    foo(c); 
} 

Beachten Sie, dass der Code nach der Kompilierung, wird erwartet, dass ein Linker-Fehler zu erhalten (I gestrippt die Definition der Funktion foo entfernt die Probe minimal zu halten), aber es sollte sauber kompilieren, soweit ich weiß.

Allerdings gibt MSVC mir diesen Fehler:

error C2893: Failed to specialize function template 'S::val> foo(T)'

Also meine Frage:

  • ist MSVC durch Zufall richtig in den Code Ablehnung? (und wenn ja, warum?)
  • wenn nicht, kann jemand eingrenzen, was es falsch macht? Wie in, ist es eine Sprachfunktion, die sie überhaupt nicht implementieren (wie zweiphasige Namenssuche nach Vorlagen) oder "nur" einen einfachen Fehler bei der Implementierung einer Funktion, die sie angeblich unterstützen?

Ich habe das Problem auf VC++ 2010 und 2012 wiedergegeben

+0

Ist es zu dieser Frage von früher heute verwandt? [Gibt es eine Garantie für die Reihenfolge der Substitution in einer Funktionsvorlage nach Typabzug?] (Http://stackoverflow.com/questions/15462336/is-there-any-guarantee-on-the-order-of-substitution-) in-a-funktion-template-nachher) –

+0

@BoPersson: Scheint nicht mit mir verwandt. Ich kann mir nichts anderes als einen Käfer vorstellen. Übrigens funktioniert es wie erwartet auf GCC 4.7.2 –

+0

Darüber hinaus verschwindet der Fehler, wenn Sie die 'enum' durch ein' int' ersetzen. Es scheint ein Fehler zu sein, der sich auf 'enum's bezieht –

Antwort

3

Nach einigen Tests selbst ausgeführt wird, scheint dies ein Compiler Fehler in MSVC zu sein. Während es mit GCC einwandfrei funktioniert, gibt MSVC kryptischen und nicht hilfreich Compiler Fehler (identisch mit denen in Ihrer Frage), wenn Sie versuchen, traits<T>::val innerhalb der Vorlage Parameter für die S< E e > Rückkehr verwenden.

Die lustige Sache ist, wenn Sie S< E e > ändern, um stattdessen eine ganze Zahl zu nehmen, funktioniert es. Betrachten Sie dieses Beispiel, identisch mit Ihnen mit etwas unterschiedlichen Namensgebung:

enum E { 
    x 
}; 

template <typename T> 
struct traits { 
    static const E val = x; 
}; 

template <E e> 
struct S { 
    S(){}; 
}; 

template <typename T> 
S< traits<T>::val > tricky(T t) { 
    return S< traits<T>::val >(); 
}; 

int main() { 
    char thiskidwhowalksaround = 0; 
    S<x> s = tricky(thiskidwhowalksaround); 
} 

Jetzt wollen wir nur eine einzige Sache ändern:

template <int e> // int instead of E 
struct S { 
    S(){}; 
}; 

das Programm dann compiliert (Links und läuft) für mich einwandfrei . Wenn Sie auch wieder auf den ursprünglichen zurückkehren, und dann in einem Wert von E direkt übergeben, wie:

template <typename T> 
S<x> tricky(T t) { 
//^here 
    return S<x>(); // <-- here 
}; 

Dann erstellt die Programmdatei. MSVC hat das Problem, bei dem es um den Staub beißt zu versuchen, Folgendes zu tun:

traits<T>::val

wo val ist jede Art von Aufzählung. Ich bin zu 99% sicher, dass dies ein Mangel im Compiler selbst ist. Das scheint C++ perfekt zu sein, so dass ich nicht sagen kann, dass GCC etwas falsch macht oder extension-y, wenn das ursprüngliche Code-Snippet funktioniert. Daher ist das Beste, was ich herausfinden kann, dass MSVC im Vergleich zu seinen Kollegen wieder eine Compiler-Robustheit aufweist.

Sie können hier aufhören zu lesen, weil ich jetzt einen kleinen Moment brauche, um über den MSVC-Compiler zu reden.

begin<rant> Es ist nicht, dass die VC++ Team schlecht ist oder dass C++ ist schlecht, aber von dem, was ich die Compiler-Team und die Standard-Bibliothek-Teams bei Microsoft aufzulesen - wie der Zeitpunkt des Schreibens - sind winzige im Vergleich zu anderen Abteilungen. Es ärgert mich, dass eine so grundlegende und wichtige Sprache und ein Teil des Kerns der MS-Industrie so wenig Arbeitskräfte hat, dass sie nicht mithalten kann, was ich in meiner kurzen Lebenszeit als einen der langsamsten Standards der Welt empfinde. Ich stoße sicherlich nicht die Leute an, die am VC++ - Team arbeiten, aber ich bin zutiefst verblüfft, warum nicht mehr von ihnen daran arbeitet, C++ nicht nur auf den neuesten Stand zu bringen, sondern den Compiler besser und so gut wie den anderen zu machen Produktbereiche. end<rant>

+0

Es war in der Tat ein Compiler-Fehler. Ich habe es auf [Connect] (https://connect.microsoft.com/VisualStudio/feedback/details/781537/failed-to-specialize-function-template#tabs) gemeldet, und sie haben nur angegeben, dass es "behoben" wird die nächste Version von Visual C++ "... Wann immer das ist – jalf

+0

@jalf: Hurray ...! Könnte sein. –

Verwandte Themen