Erinnern Sie sich, dass std::string
ist kein eigenständiger Typ, es ist wirklich eine Klassenvorlage Spezialisierung - std::basic_string<char>
. Das sehr wichtige Detail ist, dass die potenzielle Überlastung für ein std::string
Streaming nimmt kein std::string const&
Argument, es ist ein function template ist, die einen std::basic_string const&
folgert:
template <class CharT, class Traits, class Allocator>
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os,
const std::basic_string<CharT, Traits, Allocator>& str);
Template Abzug hält nie Konvertierungen. Die Namenssuche findet diese Funktionsvorlage und verwirft sie dann als nicht lebensfähig aufgrund eines Fehlschlags. S
ist kein basic_string<CharT, Traits, Allocator>
für solche Typen, also sind wir fertig. Die einzigen brauchbaren Stream-Operatoren wären alle integralen, von denen bool
die beste Übereinstimmung ist.
Wenn es speziell eine Funktion mit der Unterschrift:
std::ostream& operator<<(std::ostream&, std::string const&);
Dann würde der Anruf nicht eindeutig sein - würden Sie zwei benutzerdefinierte Konvertierungen erhalten, die gewählt wird, in äquivalenter Weise würde.
Dies ist einfach durch die Verwendung unserer eigenen Funktionen anstatt die Millionen Überlastungen für operator<<
zu überprüfen:
void foo(bool); // #1
void foo(std::string); // #2
void bar(bool); // #3
template <class C, class T, class A>
void bar(std::basic_string<C,T,A>); // #4
foo(S{}); // error: ambiguous
bar(S{}); // calls #3
Nur nitpick wird nichts jemals implizit gegossen.Typen werden implizit konvertiert, aber ein * Cast * bedeutet * explizite Konvertierung *. – StoryTeller
@StoryTeller Danke, es ist gut, die spezifische Terminologie zu kennen. Ich habe meine Frage bearbeitet. – YSC