Ihre Version von operator<<
hier ist auf einem Argument templated, und so ist die Version, die durch den Standard geliefert wird.
Das Problem liegt darin, dass Ihre Version (wir es Funktion aufrufen, werden ein) auf ein Argument Templat ist:
template<class T>
inline std::ostream& operator<<(std::ostream& os, T const& t)
{
return os;
}
und von cppreference, können Sie den Standard der Überlastung für const char*
sehen (wir ll nennen es b) auf der anderen Templat:
template< class Traits >
basic_ostream<char,Traits>& operator<<(basic_ostream<char,Traits>& os,
const char* s);
Sie können das Verhalten erhalten Sie, indem Sie Ihre Version vonerwartendie gleiche Vorlage Argument für das erste Argument verwenden (dies ist c):
template<class T, class CharT, class Traits>
inline std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, T const& t)
{
return os;
}
kompiliert glücklich, wie Sie on coliru sehen können.
Dies liegt daran, dass die Überladungsauswahl für die Vorlage die am meisten spezialisierte Vorlage auswählt, wenn eine Überladung mit mehreren möglichen Vorlagenfunktionen ausgewählt wird.
Insbesondere wird zuerst die Schablone transformiert:
[temp.func.order]:
partielle Ordnung auswählt, welche von zwei Funktionsschablonen spezialisiertere als die andere ist durch Transformieren jeder Vorlage der Reihe nach (siehe nächsten Abschnitt) und Durchführen einer Vorlagenargumentableitung unter Verwendung des Funktionstyps. Der Deduktionsprozess bestimmt, ob eine der Templates spezialisierter ist als die andere. Wenn dies der Fall ist, ist die spezialisiertere Vorlage diejenige, die durch den partiellen Bestellprozess ausgewählt wird.
Um die transformierte Vorlage für jeden Typ zu erzeugen, synthetisieren Nicht-Typ- oder Vorlagenparameter (einschließlich ihrer Template-Parameterpakete) einen eindeutigen Typ, Wert oder Klassenvorlage und ersetzen sie für jedes Vorkommen dieses Parameters im Funktionstyp der Vorlage. [Hinweis: Der Typ, der den Platzhalter im Typ des für einen nicht typisierten Vorlagenparameter synthetisierten Werts ersetzt, ist ebenfalls ein eindeutiger synthetisierter Typ. - Endnote] ...
[temp.deduct.partial]:
Zwei Sätze von Arten verwendet werden, die teilweise Ordnung zu bestimmen. Für jede der beteiligten Vorlagen gibt es den ursprünglichen Funktionstyp und den transformierten Funktionstyp. [Hinweis: Die Erstellung des transformierten Typs wird in [temp.func.order] beschrieben. - Endnote] Der Deduktionsprozess verwendet den transformierten Typ als Argumentvorlage und den Originaltyp der anderen Vorlage als Parametervorlage. Dieser Prozess wird für jeden am partiellen Sortiervergleich beteiligten Typ zweimal durchgeführt: einmal die transformierte Vorlage-1 als Argumentvorlage und Vorlage-2 als Parametervorlage und erneut die transformierte Vorlage-2 als Argumentvorlage und Vorlage-1 verwenden als Parametervorlage.
Die Typen verwendet, um die Reihenfolge zu bestimmen, von dem Kontext ab, in dem die partielle Ordnung erfolgt:
- Im Rahmen eines Funktionsaufrufs verwendeten Typen sind die Funktionsparameter Typen, für die die Funktion Aufruf hat Argumente.
...
- Funktionsvorlage F dest an wie als Funktionsvorlage G spezialisiert, wenn für jedes Paar von Arten verwendet, um die Reihenfolge zu bestimmen, die Art von F ist mindestens so groß wie die Art spezialisiert von G. F spezialisierter als G ist, wenn F dest auf als spezialisierte wie G und G nicht zumindest wie F. spezialisierte
so Wir wollen die Teile der Vorlagen, die die Funktionsargumente sind.
a) T => std::ostream&, T const&
b) CharT, Traits => std::basic_ostream<CharT, Traits>, const char*
c) T, CharT, Traits => std::basic_ostream<CharT, Traits>, T const&
Zum ersten Argument dieser Funktionen ist ein spezialisierter als b und c.
Für das zweite Argument dieser Funktionen, b ist spezialisierter als ein und c.
Wie wir in gelernt [temp.deduct.partial]/10 erfordert Argument Abzug aller relevanten Argumente einer Funktion f1 zu sein, zumindest als für die Funktion f1 als alle Argumente einer Funktion f2 spezialisiert mindestens so spezialisiert sein wie f2, ein kann hier nicht spezialisierter sein als b, da jedes ein Argument mehr spezialisiert als das andere passende Argument.
Dies ist nicht der Fall mit c, da beide ein und c alle Argumente zumindest als in c als Argumente spezialisiert.
Somit wird die Überladungsauflösung zwischen a und b weil bei der Auswahl eines mindestens so spezialisierte als b und b ist mindestens so spezialisiert wie a mehrdeutig sein. Die Mehrdeutigkeit wird durch die Verwendung c entfernt statt ein weil b mindestens so spezialisiert wie c, aber das Gegenteil ist nicht wahr.
Wie wir wissen von [temp.func.order]/2, die mehr spezialisierte Funktion gewinnt Überladungsauflösung, und mit der Verwendung von c statt ein, der Gewinner ist b und die Leitung std::cout << "hello";
druckt hello
auf die Konsole.
zeigen den vollständigen Fehler, werden die meisten Compiler die Alternativen Liste –
Ich glaube, weil es bereits eine Standard-Überlastung für diese _exists_. – ForceBru
lesen Sie diese http://stackoverflow.com/a/24088197/4743711 – Loreto