2011-04-08 33 views
6

¿Por qué esta llamada rvalue es ambigua? Puedo tener AA y AA & y el compilador sabrá usar AA&. Pero cuando agrego en la tercera opción recibo un error. Obviamente, AA & & es una mejor sobrecarga que las otras, como int para una int, es mejor que larga. ¿Por qué es esto ambiguo? ¿Hay alguna manera de mantener las 3 sobrecargas y dejar claro cuál quiero? (Typecasting (AA&&) no lo hará).¿Por qué esta llamada rvalue es ambigua?

struct AA{ 
    void*this_; 
    AA() { this_=this; } 
    //not valid, use AA&, AA(AA a){ this_=this; } 
    AA(AA&a){ this_=this; } 
    AA(AA&&a){ this_=a.this_; } 
}; 
void movetest(AA s) {} 
void movetest(AA& s) {} 
//This gets me the ambiguous error void movetest(AA&& s) {} 
AA&& movetest() { return AA(); } 
void MyTestCode2(){ 
    AA a; 
    AA b(a); 
    AA c = movetest(); 
    movetest(AA()); 
} 
+2

(En una nota, el cero-aridad 'movetest' función devuelve una referencia a una variable local.) – GManNickG

+0

(También voy Por lo general, no querrás las tres sobrecargas de todos modos.) – GManNickG

+0

@GMan: ¿Qué ... por qué? ¿eh? Tal vez se puede explicar esto, así http://stackoverflow.com/questions/5591995/is-move-by-lvalue-broken-unfinished-in-msvc2010 –

Respuesta

6

puedo tener AA y AA & y el compilador sabrá utilizar AA &

Sí, en el caso de movetest (AA());, solamente movetest (AA) es viable, ya que una (lvalue) referencia a la no-const no puede estar unido a un valor p. Sin embargo, se dice que una referencia rvalue vincula directamente a un temporal. Por lo tanto, para fines de resolución de sobrecarga de las funciones

void movetest(AA) 
void movetest(AA&&) 

son iguales, porque los secuencias de conversión implícitas utilizan para convertir AA() a AA y AA & &, respectivamente, son iguales. El primero no es mejor, porque el enlace directo de referencia también se considera una conversión de identidad.

+0

es la regla, básicamente, si usted tiene una función que toma un parámetro por valor no deberías tener otras sobrecargas? – Clinton

1

estuvo de acuerdo con decltype. Esto es realmente diferente de la de C++ 03/98 ambigüedad:

struct AA {}; 

void movetest(AA s) {} 
void movetest(AA& s) {} 

int main() 
{ 
    AA a; 
    movetest(a); 
} 

test.cpp:9:5: error: call to 'movetest' is ambiguous 
    movetest(a); 
    ^~~~~~~~ 
test.cpp:3:6: note: candidate function 
void movetest(AA s) {} 
    ^
test.cpp:4:6: note: candidate function 
void movetest(AA& s) {} 
    ^
1 error generated. 
Cuestiones relacionadas