como os valores L podem ser passados ​​para std :: make_pair

Aug 16 2020

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 ie chambos são valores-L. A resolução do argumento do modelo converte valores L em valores R ou como isso funciona?

Respostas

3 songyuanyao Aug 16 2020 at 08:06

Os parâmetros de make_pairnã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:

  1. 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.

1 JaMiT Aug 16 2020 at 11:01

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 ie chambos 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.