如何将左值传递给 std::make_pair

how can l-values be passed to std::make_pair

std::make_pairthere is only one implementation C++14 onwards

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

两个参数都是R值参考,根据this

R-values references cannot be initialized with l-values.

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

所以当我尝试在上面的代码中使用 make_pair 时,它会正确地抛出错误 error: cannot bind rvalue reference of type 'int&&' to lvalue of type 'int'.

但是,如果我更改删除模板参数并将其命名为

,它对上面的代码非常有效
mp.insert(make_pair(i, ch));

我很困惑这是如何工作的,因为 ich 都是 L 值。模板参数解析是否将 L 值转换为 R 值或类似这是如何工作的?

make_pair的参数没有声明为rvalue-reference,而是forwarding reference

Forwarding references are a special kind of references that preserve the value category of a function argument, making it possible to forward it by means of std::forward. Forwarding references are either:

  1. function parameter of a function template declared as rvalue reference to cv-unqualified type template parameter of that same function template:

template argument deduction 的帮助下,转发引用同时适用于左值和右值。当被传递一个左值时,模板参数将被推导为lvalue-reference,引用折叠后,函数参数也是lvalue-reference。传递右值时,模板参数将推导为non-reference,函数参数为rvalue-reference.

另一方面,如果像make_pair<int,char>(...)那样显式指定模板参数,则函数参数相应地变为rvalue-reference。

已经解释了大部分情况。不过,我愿意贡献如何使用显式模板参数来实现这一点。您已经走了大部分路,但没有迈出最后一步。

I'm confused how this works as i and ch both are L-values.

没错。您需要 l-values,这是您可以在模板参数中指定的内容:

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

或适用于更多情况的表格:

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

一些额外的写作,但如果参数推导由于某种原因失败则需要。