como os valores L podem ser passados para std :: make_pair
Em, std::make_pair
há apenas uma implementação C ++ 14 em diante
template <classe T1, classe T2> constexpr std :: pair <V1, V2> make_pair (T1 && t, T2 && u);
Ambos os parâmetros são referências de valor R e de acordo com este
As referências de valores R não podem ser inicializadas com valores l.
int i = 1;
char ch = 'a';
std::unordered_map<int, char> mp;
mp.insert(make_pair<int,char>(i, ch));
Então, quando tento usar make_pair como no código acima, ele gera um erro corretamente error: cannot bind rvalue reference of type 'int&&' to lvalue of type 'int'
.
No entanto, funciona perfeitamente para o código acima, se eu alterar, eliminar os argumentos do modelo e chamá-lo de
mp.insert(make_pair(i, ch));
Estou confuso como isso funciona i
e ch
ambos são valores-L. A resolução do argumento do modelo converte valores L em valores R ou como isso funciona?
Respostas
Os parâmetros de make_pair
não são declarados como rvalue-reference, mas como referência de encaminhamento .
As referências de encaminhamento são um tipo especial de referência que preserva a categoria de valor de um argumento de função, tornando possível encaminhá-lo por meio de std :: forward. As referências de encaminhamento são:
- parâmetro de função de um modelo de função declarado como referência rvalue para o parâmetro de modelo de tipo cv-unqualified desse mesmo modelo de função:
A referência de encaminhamento funciona com lvalues e rvalues, com a ajuda da dedução do argumento do modelo . Ao ser passado um lvalue, o parâmetro do modelo seria deduzido como lvalue-reference, após o colapso da referência, o parâmetro de função é lvalue-reference também. Ao passar um rvalue, o parâmetro do template seria deduzido como não referência, o parâmetro da função é rvalue-reference.
Por outro lado, se você especificar o argumento do modelo explicitamente como make_pair<int,char>(...)
, o parâmetro da função se tornará a referência rvalue de acordo.
A resposta de songyuanyao já explica a maior parte do que está acontecendo. Gostaria, no entanto, de contribuir como fazer isso funcionar com argumentos de modelo explícitos. Você já estava quase lá, mas não deu o último passo.
Estou confuso como isso funciona
i
ech
ambos são valores-L.
Exatamente. Você quer valores l, que é algo que você pode especificar nos argumentos do modelo:
std::make_pair<int &, char &>(i, ch)
ou um formulário que funciona em mais casos:
std::make_pair<const int &, const char &>(i, ch)
Um pouco de escrita extra, mas necessário se a dedução do argumento falhar por algum motivo.