как можно передать l-значения в std :: make_pair

Aug 16 2020

В std::make_pair есть только одна реализация C ++ 14 года

шаблон <класс T1, класс T2> constexpr std :: pair <V1, V2> make_pair (T1 && t, T2 && u);

Оба параметра являются справочными значениями R и в соответствии с этим

Ссылки на R-значения не могут быть инициализированы l-значениями.

    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));

Я не понимаю, как это работает, iи chоба являются L-значениями. Преобразует ли разрешение аргументов шаблона L-значения в R-значения или как это работает?

Ответы

3 songyuanyao Aug 16 2020 at 08:06

Параметры make_pairобъявляются не как rvalue-reference, а как ссылка на пересылку .

Ссылки пересылки - это особый вид ссылок, которые сохраняют категорию значения аргумента функции, что позволяет пересылать его с помощью std :: forward. Ссылки на пересылку:

  1. параметр функции шаблона функции объявлен как ссылка rvalue на параметр шаблона типа cv-unqualified того же шаблона функции:

Ссылка на пересылку работает как с lvalue, так и с rvalue, с помощью вывода аргументов шаблона . При передаче lvalue параметр шаблона будет выведен как lvalue-reference, после сворачивания ссылки параметр функции также будет lvalue-reference. При передаче rvalue параметр шаблона будет выведен как не-ссылка, параметром функции будет rvalue-reference.

С другой стороны, если вы явно укажете аргумент шаблона like make_pair<int,char>(...), параметр функции станет соответственно rvalue-reference.

1 JaMiT Aug 16 2020 at 11:01

Ответ на songyuanyao уже объясняет большую часть того, что происходит. Однако я хотел бы внести свой вклад, как заставить эту работу работать с явными аргументами шаблона. Вы прошли почти весь путь, но не сделали последнего шага.

Я не понимаю, как это работает, iи chоба являются L-значениями.

Точно. Вам нужны l-значения, которые вы можете указать в аргументах шаблона:

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

или форма, которая работает в большем количестве случаев:

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

Немного дополнительной записи, но она необходима, если по какой-то причине вывод аргумента не удается.