Überladungsauflösung zwischen Objekt, rvalue-Referenz, const-Referenz

Lesezeit: 3 Minuten

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.

  • Sie geben an int&& im Code dann aber verallgemeinern T&& 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


Benutzer-Avatar
Andreas Tomassos

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.

  • Also haben sowohl gcc als auch clang recht: if f(int) und f(int&&) in Betracht gezogen werden, ist die Überlastung zweideutig, und das gleiche für f(int) und f(int const&).

    – Yakk – Adam Nevraumont

    31. Juli 2013 um 14:04 Uhr

  • @Jakk: “Wenn f(int) und f(int&&) berücksichtigt werden, ist die Überladung mehrdeutig” Fast. Wenn es keine beste Übereinstimmung gibt, ist die Überladung mehrdeutig. Annehmen f(int), f(int&&) und f(double) waren lebensfähig für einen Anruf von f(2.0). f(double) ist die beste Übereinstimmung, obwohl f(int) und f(int&&) kommen in Betracht.

    – Andreas Tomazos

    31. Juli 2013 um 23:39 Uhr


1013150cookie-checkÜberladungsauflösung zwischen Objekt, rvalue-Referenz, const-Referenz

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy