2011-08-10 15 views
15

Recientemente me he hecho a la idea de los conceptos de glvalues, xvalues ​​y prvalues ​​de C++ 0x, así como las referencias de rvalue. Sin embargo, hay una cosa que todavía me escapa:¿Qué es una referencia rvalue al tipo de función?

¿Qué es "una referencia de valor al tipo de función"? Literalmente se menciona muchas veces en los borradores. ¿Por qué se introdujo tal concepto? ¿Cuáles son los usos para eso?

+0

¿finalmente entendiste la respuesta? He dejado un comentario debajo de la respuesta, así que si conoce la aclaración por favor bríndelo. gracias –

Respuesta

15

me gusta ser circular, pero una referencia rvalue funcione t ype es una referencia rvalue al tipo de función. Existe tal tipo de función, p. Ej. void(). Y puede formar una referencia de valor real a ella.

En términos del sistema de clasificación introducido por N3055, es un valor x.

Sus usos son raros y oscuros, pero no es inútil. Consideremos, por ejemplo:

void f() {} 
... 
auto x = std::ref(f); 

x tiene que escribir:

std::reference_wrapper<void()> 

Y si nos fijamos en la sinopsis de reference_wrapper Incluye:

reference_wrapper(T&) noexcept; 
reference_wrapper(T&&) = delete; // do not bind to temporary objects 

En este ejemplo T es el tipo de función void() . Por lo tanto, la segunda declaración forma una referencia rvalue al tipo de función con el fin de garantizar que reference_wrapper no se pueda construir con un argumento rvalue. Ni siquiera si T es const.

Si no fuera legal formar una referencia rvalue a la función, esta protección daría como resultado un error de tiempo de compilación incluso si no pasamos un valor T al constructor.

+3

Creo que quería decir 'void()'. 'void()()' era una demanda errónea de GCC/binutils pero [se arregló hace algún tiempo] (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46332). –

+1

@Johannes: ¡Gracias! ¡Eso fue * la mayoría * útil! –

+0

Esto es escalofriante y tengo problemas para entenderlo. Acerca de la última oración sobre el error de tiempo de compilación, ¿SFINAE no causaría que se ignore la segunda declaración en este caso? – Kos

0

En la antigua norma C++ la siguiente está prohibido:

int foo(); 
void bar(int& value); 

int main() 
{ 
    bar(foo()); 
} 

porque el tipo de retorno de foo() es un valor p y se pasa por referencia a la barra().

esto era permitido, aunque con extensiones de Microsoft habilitadas en Visual C++ ya que (creo) 2005.

soluciones posibles sin C++ 0x (o msvc) se declaran

void bar(const int& value); 

o utilizando una temp variable, almacenando el retorno de valor de foo() y pasando la variable (como referencia) a la barra():

int main() 
{ 
    int temp = foo(); 
    bar(temp); 
} 
+5

Tal vez entendí mal la pregunta, pero creo que el OP está hablando de referencia de valores a los tipos de funciones (es decir, lambdas, etc.). – user786653

Cuestiones relacionadas