Bei allen drei Funktionen ist dieser Aufruf mehrdeutig.
int f( int );
int f( int && );
int f( int const & );
int q = f( 3 );
Entfernen f( int )
bewirkt, dass sowohl Clang als auch GCC die rvalue-Referenz der lvalue-Referenz vorziehen. Aber stattdessen führt das Entfernen einer der Referenzüberladungen zu Mehrdeutigkeiten mit f( int )
.
Die Überlastungsauflösung erfolgt normalerweise in Form einer strengen Teilordnung, aber int
scheint äquivalent zu zwei Dingen zu sein, die einander nicht äquivalent sind. Welche Regeln gelten hier? Ich meine mich an eine diesbezügliche Mängelanzeige zu erinnern.
Gibt es eine Chance int &&
kann gegenüber bevorzugt werden int
in einer zukünftigen Norm? Die Referenz muss an einen Initialisierer gebunden werden, während der Objekttyp nicht so eingeschränkt ist. Also Überladung zwischendurch T
und T &&
könnte effektiv bedeuten “das vorhandene Objekt verwenden, wenn mir das Eigentum übertragen wurde, andernfalls eine Kopie erstellen”. (Dies ähnelt der reinen Wertübergabe, erspart jedoch den Overhead des Verschiebens.) Da diese Compiler derzeit funktionieren, muss dies durch Überladen erfolgen T const &
und T &&
, und explizites Kopieren. Aber ich bin mir nicht einmal sicher, ob das wirklich Standard ist.
Welche Regeln gelten hier?
Da es nur einen Parameter gibt, ist die Regel, dass einer der drei möglichen Parameter-Initialisierungen dieser Parameter sein muss eine bessere Übereinstimmung als beide die anderen zwei. Wenn zwei Initialisierungen verglichen werden, ist entweder eine besser als die andere oder keine besser (sie sind nicht unterscheidbar).
Ohne spezielle Regeln zur direkten Referenzbindung wären alle drei genannten Initialisierungen nicht unterscheidbar (bei allen drei Vergleichen).
Die Sonderregelungen über die Direktbezugsbindung machen int&&
besser als const int&
aber weder ist besser noch schlechter als int
. Daher gibt es keine beste Übereinstimmung:
S1 S2
int int&& indistinguishable
int const int& indistinguishable
int&& const int& S1 better
int&&
ist besser als const int&
wegen 13.3.3.2:
S1 und S2 sind Referenzbindungen (8.5.3) und beziehen sich nicht auf einen impliziten Objektparameter einer nicht statischen Elementfunktion, die ohne Ref-Qualifizierer deklariert ist, und S1 bindet eine rvalue-Referenz an einen rvalue und S2 bindet eine lvalue-Referenz.
Diese Regel gilt jedoch nicht, wenn eine der Initialisierungen keine Referenzbindung ist.
Besteht die Möglichkeit, dass int && in einem zukünftigen Standard gegenüber int bevorzugt wird? Die Referenz muss an einen Initialisierer gebunden werden, während der Objekttyp nicht so eingeschränkt ist. Das Überladen zwischen T und T && könnte also effektiv bedeuten: “Benutze das vorhandene Objekt, wenn ich das Eigentum erhalten habe, andernfalls erstelle eine Kopie.”
Sie schlagen vor, eine Referenzbindung zu einer besseren Übereinstimmung zu machen als eine Nicht-Referenzbindung. Warum posten Sie Ihre Idee nicht unter isocpp Zukunftsvorschläge. SO ist nicht das Beste für subjektive Diskussionen / Meinungen.
Sie geben an
int&&
im Code dann aber verallgemeinernT&&
in der Frage, obwohl sie unterschiedlich sind. Welches ist es?– Raptz
31. Juli 2013 um 4:44 Uhr
@Rapptz sagte ich nur
T
wenn es um mögliche Bedeutung im realen Gebrauch geht. Ich will keine perfekte Weiterleitung vorschlagen, das ist ein ganz anderes Ballspiel.– Kartoffelklatsche
31. Juli 2013 um 4:45 Uhr