как можно передать l-значения в std :: make_pair
В 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-значения или как это работает?
Ответы
Параметры make_pair
объявляются не как rvalue-reference, а как ссылка на пересылку .
Ссылки пересылки - это особый вид ссылок, которые сохраняют категорию значения аргумента функции, что позволяет пересылать его с помощью std :: forward. Ссылки на пересылку:
- параметр функции шаблона функции объявлен как ссылка rvalue на параметр шаблона типа cv-unqualified того же шаблона функции:
Ссылка на пересылку работает как с lvalue, так и с rvalue, с помощью вывода аргументов шаблона . При передаче lvalue параметр шаблона будет выведен как lvalue-reference, после сворачивания ссылки параметр функции также будет lvalue-reference. При передаче rvalue параметр шаблона будет выведен как не-ссылка, параметром функции будет rvalue-reference.
С другой стороны, если вы явно укажете аргумент шаблона like make_pair<int,char>(...)
, параметр функции станет соответственно rvalue-reference.
Ответ на songyuanyao уже объясняет большую часть того, что происходит. Однако я хотел бы внести свой вклад, как заставить эту работу работать с явными аргументами шаблона. Вы прошли почти весь путь, но не сделали последнего шага.
Я не понимаю, как это работает,
i
иch
оба являются L-значениями.
Точно. Вам нужны l-значения, которые вы можете указать в аргументах шаблона:
std::make_pair<int &, char &>(i, ch)
или форма, которая работает в большем количестве случаев:
std::make_pair<const int &, const char &>(i, ch)
Немного дополнительной записи, но она необходима, если по какой-то причине вывод аргумента не удается.