C++ 0x referencia constante de RValue como parámetro de función
c++11 lvalue (2)
La resolución de sobrecarga prefiere const rvalue sobre const lvalue porque, bueno, es un rvalue y lo está vinculando a una referencia de rvalue, pero tiene que agregar const en ambos casos, por lo que definitivamente se prefiere la referencia de rvalue.
Tales cosas generalmente no tienen sentido, es mejor dejarlas vinculadas a las sobrecargas constantes de valores. Los valores constantes no tienen ningún uso real.
Estoy tratando de entender por qué alguien escribiría una función que toma una referencia constante .
En el ejemplo de código a continuación, ¿cuál es el propósito de la función de referencia de valor constante (que devuelve "3"). ¿Y por qué la resolución de sobrecarga prefiere el valor constante de const sobre la función de referencia const LValue (devolviendo "2").
#include <string>
#include <vector>
#include <iostream>
std::vector<std::string> createVector() { return std::vector<std::string>(); }
//takes movable rvalue
void func(std::vector<std::string> &&p) { std::cout << "1"; }
//takes const lvalue
void func(const std::vector<std::string> &p) { std::cout << "2"; }
//takes const rvalue???
//what is the point of const rvalue? if const I assume it is not movable?
void func(const std::vector<std::string> &&p) { std::cout << "3"; }
int main()
{
func(createVector());
return 0;
}
Los valores de L prefieren encarecidamente la vinculación a las referencias de valor de l, y, de manera similar, las referencias de valor de r prefieren la unión a las referencias de valor de r. Las expresiones modificables prefieren débilmente el enlace a una referencia no constante.
Entonces, cuando su compilador está haciendo una resolución de sobrecarga, verifica si hay una sobrecarga que tome una referencia de valor, porque se prefiere fuertemente. En este caso, dado que la expersión es un rvalor modificable, la sobrecarga de referencia del rvalor gana.
En realidad, se usa para referencias const rvalue, se pueden usar para asegurarse de que algo no se vincule a un rvalue. Recuerde que un valor de r se une a una referencia de valor de const, por lo tanto, si lo hizo:
template <typename T> void foo(const T& bar) { /* ... */ }
Y llamó a la función con:
foo(createVector());
Funcionaría bien. Sin embargo, a veces se desea asegurarse de que solo pueda pasar valores de l a una función (este es el caso de std::ref
para uno). Puedes lograr esto agregando una sobrecarga:
template <typename T> void foo(const T&&) = delete;
Recuerde, los valores r prefieren encarecidamente la vinculación a las referencias rvalue, y las expresiones modificables prefieren la vinculación débil a las referencias no constantes. Ya que tenemos una referencia de valor constante, básicamente significa que todos los valores se unirán a esto, por lo tanto, si intentas pasar un valor a foo()
, tu compilador dará un error. Esta es la única forma de lograr dicha funcionalidad y, por lo tanto, a veces es útil.