comment les valeurs l peuvent-elles être passées à std :: make_pair

Aug 16 2020

Il std::make_pair n'y a qu'une seule implémentation à partir de C ++ 14

template <classe T1, classe T2> constexpr std :: pair <V1, V2> make_pair (T1 && t, T2 && u);

Les deux paramètres sont des références à valeur R et selon cette

Les références de valeurs R ne peuvent pas être initialisées avec des valeurs l.

    int i = 1;
    char ch = 'a';
    std::unordered_map<int, char> mp;
    mp.insert(make_pair<int,char>(i, ch));

Ainsi, lorsque j'essaye d'utiliser make_pair comme dans le code ci-dessus, cela génère correctement une erreur error: cannot bind rvalue reference of type 'int&&' to lvalue of type 'int'.

Cependant, cela fonctionne parfaitement pour le code ci-dessus si je modifie les arguments du modèle et l'appelle comme

mp.insert(make_pair(i, ch));

Je ne comprends pas comment cela fonctionne iet les chdeux sont des valeurs L. La résolution des arguments de modèle convertit-elle les valeurs L en valeurs R ou comment cela fonctionne-t-il?

Réponses

3 songyuanyao Aug 16 2020 at 08:06

Les paramètres de make_pairne sont pas déclarés comme rvalue-reference, mais comme référence de transmission .

Les références de transfert sont un type spécial de références qui préservent la catégorie de valeur d'un argument de fonction, ce qui permet de le transmettre au moyen de std :: forward. Les références de transfert sont soit:

  1. paramètre de fonction d'un modèle de fonction déclaré comme référence rvalue au paramètre de modèle de type cv-unqualified de ce même modèle de fonction:

Le renvoi de référence fonctionne à la fois avec les valeurs lvalues ​​et rvalues, à l'aide de la déduction des arguments de modèle . Lors de la transmission d'une lvalue, le paramètre de modèle serait déduit comme lvalue-reference, après la réduction de la référence, le paramètre de fonction est également lvalue-reference. Lors du passage d'une rvalue, le paramètre de modèle serait déduit comme non-référence, le paramètre de fonction est rvalue-reference.

D'un autre côté, si vous spécifiez explicitement l'argument du modèle comme make_pair<int,char>(...), le paramètre de fonction devient rvalue-reference en conséquence.

1 JaMiT Aug 16 2020 at 11:01

La réponse de songyuanyao explique déjà l'essentiel de ce qui se passe. Je voudrais, cependant, contribuer à faire fonctionner cela avec des arguments de modèle explicites. Vous étiez la plupart du temps là-bas, mais vous n'avez pas fait le dernier pas.

Je ne comprends pas comment cela fonctionne iet les chdeux sont des valeurs L.

Exactement. Vous voulez des valeurs l, ce que vous pouvez spécifier dans les arguments du modèle:

std::make_pair<int &, char &>(i, ch)

ou un formulaire qui fonctionne dans plus de cas:

std::make_pair<const int &, const char &>(i, ch)

Un peu d'écriture supplémentaire, mais nécessaire si la déduction d'argument échoue pour une raison quelconque.