Почему std :: make_tuple превращает std :: reference_wrapper & lt; X & gt; аргументы в X & amp;?

В стандарте 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&,

Я задаюсь вопросом: почему справочные обертки рассматриваются здесь особенным образом?

10

Решение

Это более или менее основная цель 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,

11

Другие решения

Ваш заголовок вводит в заблуждение: используя std::reference_wrapper<X> превращает членов быть X& скорее, чем X, Причина этого преобразования заключается в том, что std::reference_wrapper<T> вспомогательный тип, предназначенный для преобразования типа значения в ссылочный тип. Тем не менее, дополнительное преобразование, необходимое для того, чтобы он выглядел таким образом, иногда мешает использованию. Таким образом, разворачивание ссылки, где это возможно, кажется разумным подходом: std::tuple<...> член а T& делает использование более естественным.

4

Люди обычно используют std::reference_wrapper<X> держать не копируемые типы. Поэтому, копируя их в make_tuple побьет цель (и может нарушить сборку, если конструктор копирования будет удален). По этой причине он использует ссылку (вместо значения) в своем типе возвращаемого значения.

0
По вопросам рекламы [email protected]