В стандарте C ++ 11 говорится, что (см. cppreference.com, см. также раздел 20.4.2.4 стандарта) в нем говорится, что
template< class... Types >
tuple<VTypes...> make_tuple( Types&&... args );
Создает объект кортежа, выводя целевой тип из типов аргументов.
Для каждого
Ti
вTypes...
, соответствующий типVi
вVtypes...
являетсяstd::decay<Ti>::type
если применениеstd::decay
результаты вstd::reference_wrapper<X>
для какого-то типаX
в этом случае выведенный типX&
,
Я задаюсь вопросом: почему справочные обертки рассматриваются здесь особенным образом?
Это более или менее основная цель reference_wrapper
,
Обычно, std::make_tuple
всегда делает кортежи ценности (std::decay
имитирует семантику передачи по значению). Дано int x, y; std::make_tuple(x, y);
делает std::tuple<int, int>
даже если это выведет Types
как пакет ссылок int&, int&
, std::decay
преобразует их в int, int
,
reference_wrapper
позволяет форсировать создание кортежей Рекомендации: std::make_tuple(std::ref(x), y)
сделаю std::tuple<int&, int>
,
Другие части стандартного использования библиотеки reference_wrapper
таким же образом. В качестве примера, std::bind
обычно копирует / перемещает связанные аргументы в результирующий объект, но если вы хотите, чтобы он хранил только ссылку, вы можете явно запросить его, передав reference_wrapper
,
Ваш заголовок вводит в заблуждение: используя std::reference_wrapper<X>
превращает членов быть X&
скорее, чем X
, Причина этого преобразования заключается в том, что std::reference_wrapper<T>
вспомогательный тип, предназначенный для преобразования типа значения в ссылочный тип. Тем не менее, дополнительное преобразование, необходимое для того, чтобы он выглядел таким образом, иногда мешает использованию. Таким образом, разворачивание ссылки, где это возможно, кажется разумным подходом: std::tuple<...>
член а T&
делает использование более естественным.
Люди обычно используют std::reference_wrapper<X>
держать не копируемые типы. Поэтому, копируя их в make_tuple
побьет цель (и может нарушить сборку, если конструктор копирования будет удален). По этой причине он использует ссылку (вместо значения) в своем типе возвращаемого значения.