2015-07-16 10 views
8

Betrachten Sie folgenden Code ein:Ist das Überladen der Funktion durch Referenz zulässig, wenn keine Mehrdeutigkeit besteht?

#include <iostream> 

void foo(int m); 
void foo(int &k); 

int main() 
{ 
    foo(5); // ok, because there is no ambiguity 

    int m = 5; 
    //foo(m); // compile-time error, because of ambiguity 
    foo(m + 0); // ok, because it's an expression of type int and not object's lvalue 
} 

void foo(int m) 
{ 
    std::cout << "by value\n"; 
} 
void foo(int &k) 
{ 
    std::cout << "by reference\n"; 
} 

Ich verstehe, dass es Mehrdeutigkeit für foo(m) einführt, aber dies erlaubt, wenn die Expression von Typ int (oder einem anderen, den int umgewandelt werden kann)?

Ich habe versucht, einige Standard-Referenz zu finden, aber ohne Glück.


Haftungsausschluss: Beachten Sie, dass es nicht von Function Overloading Based on Value vs. Const Reference Duplikat ist. Die const Referenzen sind unterschiedlich, da sie rvalues ​​ zugeordnet werden können, im Gegensatz zu "gewöhnlichen", nicht const Referenzen.

+1

'm' ist auch ein Ausdruck des Typs' int'. –

+1

mögliches Duplikat von [Funktionsüberladung basierend auf Wert gegenüber Const-Referenz] (http://stackoverflow.com/questions/5465293/function-overloading-based-on-value-vs-const-reference) –

Antwort

7

Ja, es ist erlaubt.

Es gibt keine Regel, um diese Überlastung zu verhindern.

[C++14: 13.1/1]: Nicht alle Funktionsdeklarationen können überladen werden. Diejenigen, die nicht überladen werden können, werden hier angegeben. [..]

[C++14: 13.1/2]:(bla bla viele Ausnahmen nicht für diesen Fall einschließlich)

Es wäre extrem für die Sprache zu begrenzen seiner Funktion zu verbieten, Überlastungen, dass mehrdeutig sein können in bestimmten Szenarien mit bestimmten Anrufen, und ohne guten Grund könnte ich hinzufügen!

9

13.1 [over.load] ist ziemlich klar (abgesehen von einer mehrseitigen Notiz), welche Funktionen nicht im selben Umfang überladen werden können.

Ihr Fall ist dort nicht aufgeführt, und Sie können diese Überlastungen deklarieren, Sie können sie einfach nicht einfach verwenden. Sie könnten der L-Wert ein wie so nennen:

void (*f)(int&) = foo; 
f(m); 

Dies vermeidet die Mehrdeutigkeit, was geschieht, wenn Sie foo(m) nennen.

Abgesehen: Ein andere Weise foo(m + 0) zu schreiben ist einfach foo(+m), der unären + Bediener den L-Wert zu einem R-Wert umwandelt, so dass die Überlast foo(int) genannt wird.

+0

Obwohl dies nicht geht Arbeit für Konstrukteure. –