2016-06-27 3 views
2

Versucht, another question zu verstehen, habe ich das Beispiel mit dem folgenden Code vereinfacht.clang ++ automatischer Rückgabetypfehler für die Spezialisierung der Vorlagenmethode in der Vorlagenklasse?

template <bool> 
struct foo 
{ 
    template <typename T> 
     auto bar (int i) 
     { return i; } 
}; 

template <> 
template <typename T> 
    auto foo<true>::bar (int i) 
    { return i; } 

int main() 
{ 
    return 0; 
} 

g ++ 4.9.2 kompilieren Sie es ohne Problem; Klirren ++ 3.5 Die folgende Fehler

tmp_003-14,gcc,clang.cpp:12:20: error: out-of-line definition of 'bar' does not 
     match any declaration in 'foo<true>' 
    auto foo<true>::bar (int i) 
        ^~~ 

Setzt man eine der beiden auto Rückkehr Werte mit int geben, gibt es keine Änderungen: g ++ Kompilieren und Klirren ++ geben den Fehler. Wenn der Fehler auto durch int ersetzt wird, verschwindet der Fehler.

Der template <typename T> Teil ist von Bedeutung, da der folgende Code problemlos mit beiden Compilern

template <bool> 
struct foo 
{ 
     auto bar (int i) 
     { return i; } 
}; 

template <> 
    auto foo<true>::bar (int i) 
    { return i; } 

int main() 
{ 
    return 0; 
} 

Meine Frage liegt auf der Hand: wer Recht hat?

g ++ oder clang ++?

Ich nehme an, dass g ++ richtig ist und dass dies ein Bug von clang ++ ist, aber ich bitte um Bestätigung.

ps.entschuldigung für mein schlechtes Englisch.

+1

Try gcc 6.1 und klirren 3.8 .. –

+1

Das war ein Clang Problem. Es funktioniert mit 3.8: https://godbolt.org/g/JkCJ6l – refi64

Antwort

0

Ich hatte das gleiche Problem, hier ist die solution. Außer Sie sollten auch berücksichtigen, dass implizite automatische Rückgabetyp nur seit C++ 14 zulässig ist, so sollten Sie entweder -std=c++14 Kompilierungsflag verwenden oder explizit den Rückgabetyp (für C++ 11) festlegen.

Das Problem ist, dass CLang keine gute Spezialisierung der Template-Funktionen der Template-Klasse entspricht. Um dies zu überwinden, sollten Sie eine leere Deklaration der Template-Klasse und eine separate Spezialisierungen haben:

template <bool> 
struct foo; 

template <> 
struct foo <false> 
{ 
    template <typename T> 
    auto bar (int i) 
    { return i; } 
}; 


template <> 
struct foo <true> 
{ 
    template <typename T> 
    auto bar (int i) 
    { return i; } 
}; 

int main() 
{ 
    return 0; 
} 
+0

Danke für Ihre Bemühungen, aber Ihr Link zu "Lösung" ist der gleiche Link zu der "anderen Frage", die ich in meiner Frage anführen. Und die akzeptierte "Lösung" ist meine Antwort auf diese Frage. Und, natürlich, wo wir über C++ 14, nicht C++ 11 sprechen, wie getaggt (es gibt kein C++ 11-Tag). Meine Frage ist nicht "wie zu lösen?" aber "wer hat recht?". Sie sagen (wenn ich richtig verstehe) "g ++ ist richtig und clang ++ ist falsch". Aber ich habe in einer Antwort gehofft, die den relevanten Teil des offiziellen Standards zitiert. (Entschuldigung nochmal für mein schlechtes Englisch). – max66

+0

Hallo @ max66, tut mir leid, dass ich dich nicht sofort erkannt habe, du warst der Typ, der zuerst die Lösung lieferte. Für mich gibt es keine Frage "wer hat Recht": Der Standard erlaubt Template-Deklaration, die auch die Definition ist und erlaubt Template-Spezialisierung. Offensichtlich fehlt es CLang nur an der Vorlagefunktionsdefinition der Vorlagenklassenspezialisierung, wenn die Vorlagenklassendeklaration ebenfalls ihre Definition ist. Es ist kein CLand Bug, nur noch nicht implementiertes Feature, denn CLang ist jung und CLang 3.8.1 kompatibel zu GCC 4.2.1 (was eine ziemlich alte Version ist). – luart

Verwandte Themen