¿Cómo se pueden pasar los valores l a std :: make_pair?
En std::make_pair
solo hay una implementación C ++ 14 en adelante
plantilla <clase T1, clase T2> constexpr std :: par <V1, V2> make_pair (T1 && t, T2 && u);
Ambos parámetros son referencias de valor R y de acuerdo con este
Las referencias de valores R no se pueden inicializar con valores l.
int i = 1;
char ch = 'a';
std::unordered_map<int, char> mp;
mp.insert(make_pair<int,char>(i, ch));
Entonces, cuando trato de usar make_pair como en el código anterior, arroja un error correctamente error: cannot bind rvalue reference of type 'int&&' to lvalue of type 'int'
.
Sin embargo, funciona perfectamente para el código anterior si cambio, suelto los argumentos de la plantilla y lo llamo como
mp.insert(make_pair(i, ch));
Estoy confundido de cómo funciona esto i
y ch
ambos son valores L. ¿La resolución del argumento de la plantilla convierte los valores L en valores R o le gusta cómo funciona esto?
Respuestas
Los parámetros de make_pair
no se declaran como rvalue-reference, sino como referencia de reenvío .
Las referencias de reenvío son un tipo especial de referencias que preservan la categoría de valor de un argumento de función, lo que hace posible reenviarlo mediante std :: forward. Las referencias de reenvío son:
- parámetro de función de una plantilla de función declarada como referencia rvalue al parámetro de plantilla de tipo cv-no calificado de esa misma plantilla de función:
La referencia de reenvío funciona tanto con lvalues como con rvalues, con la ayuda de la deducción de argumentos de plantilla . Cuando se pasa un lvalue, el parámetro de plantilla se deducirá como lvalue-reference, después de colapsar la referencia, el parámetro de la función también es lvalue-reference. Al pasar un rvalue, el parámetro de plantilla se deduciría como no referencia, el parámetro de función es rvalue-reference.
Por otro lado, si especifica el argumento de plantilla explícitamente como make_pair<int,char>(...)
, el parámetro de la función se convierte en rvalue-reference en consecuencia.
La respuesta de songyuanyao ya explica la mayor parte de lo que está sucediendo. Sin embargo, me gustaría contribuir a cómo hacer que esto funcione con argumentos de plantilla explícitos. Estuvo la mayor parte del camino, pero no dio el último paso.
Estoy confundido de cómo funciona esto
i
ych
ambos son valores L.
Exactamente. Quiere valores l, que es algo que puede especificar en los argumentos de la plantilla:
std::make_pair<int &, char &>(i, ch)
o una forma que funciona en más casos:
std::make_pair<const int &, const char &>(i, ch)
Un poco de escritura adicional, pero necesaria si la deducción del argumento falla por alguna razón.