Насколько я понимаю, initializer_list
s передают все по константной ссылке. move
с одного, наверное, небезопасно. Конструктор initializer_list
vector
скопирует каждый из элементов.
Вот несколько ссылок: initializer_list и семантика перемещения
Нет, это не сработает так, как задумано; вы все равно получите копии. Я очень удивлен этим, так как я думал, что initializer_list существует для хранения массива временных файлов, пока они не будут перемещены.
begin и end для initializer_list return const T *, поэтому результатом перемещения в вашем коде будет T const && - неизменяемая ссылка на rvalue. От такого выражения невозможно избавиться. Он будет привязан к параметру функции типа T const &, потому что rvalue действительно привязывается к ссылкам const lvalue, и вы по-прежнему будете видеть семантику копирования.
Безопасно ли перемещать элементы список инициализаторов?
initializer_list предоставляет только константный доступ к своим элементам. Вы можете использовать const_cast для компиляции этого кода, но тогда ходы могут закончиться неопределенным поведением (если элементы initializer_list действительно const). Так что делать этот переезд небезопасно. Для этого есть обходные пути, если вам это действительно нужно.
Могу ли я инициализировать список-инициализировать вектор тип только для перемещения?
Синопсис 18.9 достаточно ясно показывает, что элементы списка инициализаторов всегда передаются через константную ссылку. К сожалению, в текущей версии языка не существует способа использования семантики перемещения в элементах списка инициализаторов.
вопросы, касающиеся дизайна std :: initializer_list
Из раздела 18.9 стандарта C ++:
Объект типа initializer_list обеспечивает доступ к массиву объектов типа const E. [Примечание: пара указателей или указатель плюс длина будут очевидными представлениями для initializer_list. initializer_list используется для реализации списков инициализаторов, как указано в 8.5.4. Копирование списка инициализаторов не копирует базовые элементы. - конец примечания]
Я думаю, что причина большинства этих вещей в том, что std :: initializer_list на самом деле не является контейнером. У него нет семантики значения, у него есть семантика указателя. Это становится очевидным из последней части цитаты: копирование списка инициализаторов не копирует базовые элементы. Поскольку они были предназначены исключительно для целей инициализации, я не думаю, что это так удивительно, что вы не получаете всех тонкостей более надежных контейнеров, таких как кортежи.
Если я правильно понимаю последнюю часть, это означает, что необходимы два набора копий, поскольку initializer_list
не копирует базовые элементы. (Предыдущая цитата актуальна только в том случае, если вы пытаетесь использовать initializer_list
без копирования элементы.)
Какова основная структура std :: initializer_list?
Нет, вы не можете перейти от элементов initializer_list, поскольку элементы initializer_list должны быть неизменными (см. Первое предложение абзаца, цитируемого выше). Это также причина того, почему только функции-члены с квалификацией const предоставляют вам доступ к элементам.
Если хотите, можете использовать emplace_back
:
vec.emplace_back(TS());
vec.emplace_back(TS());
vec.push_back(std::move(ts1));
vec.push_back(std::move(ts2));
person
Community
schedule
10.12.2013
std::initializer_list<TS>
и копируются = ›два вызова конструктора копирования для каждого аргумента. Вы можете переместить их вinitializer_list
(std::vector<TS> vec {std::move(ts1), std::move(ts2)};
), но вы не можете переместить их, поэтому необходим хотя бы один вызов конструктора копирования. - person dyp   schedule 10.12.2013std::vector
, называемое à lavector<TS> vec( collect_references(ts1, ts2) );
. - person dyp   schedule 10.12.2013value_type
. Он должен возвращать тип сtemplate<class T> operator std::vector<T>() const
, чтобы вывестиvalue_type
для инициализируемого вектора; затем он может использоватьemplace_back
и по возможности избегать любого copy-ctor. Живой пример - person dyp   schedule 10.12.2013std::forward
соответственно;) Исправлен живой пример - person dyp   schedule 11.12.2013auto function_name(parameter_list) -> return_type
- это просто еще один способ записиreturn_type function_name(parameter_list)
(где вы можете использовать имена параметров в возвращаемом типе);Ts&&...
здесь объявляет пакет параметров функции, где каждый параметр является универсальной ссылкой. Я согласен с тем, что это сложно, но это должно быть невидимо для пользователяcollect_references
. Каждый переданный вами аргумент просто перенаправляется наvec.emplace_back
вызов без какого-либо преобразования, копирования или перемещения. - person dyp   schedule 11.12.2013std::move
для хранения ссылки rvalue в сборщике ссылок; тогда аргумент будет перемещен ровно один раз (вvector
) и никогда не будет скопирован. Если вы передадите lvalue, аргумент будет скопирован ровно один раз (вvector
). - person dyp   schedule 11.12.2013