std::vector construct_vector(Foo && foo) { std::vector vec; vec.emplace_back(std::move(foo)); return vec; }
Почему это так случается? Из-за отсутствия оптимизации std::initializer_list. Конструкция вектора через std::vector{} создаёт initializer_list, мувает в него один элемент foo, затем копирует из initializer_list внутрь вектора. К сожалению.
construct_vector
же копированием foo не занимается, а делает move construction. Значение вектора попадает в место вызова без копирования, через RVO.Ну вот так хреново пока работаем с std::initializer_list. В стандарте C14 про это вот что есть: "the underlying array is copy-initialized". Опаньки.
Типичный C++, что ни фича, то засада. JavaScript и то без копирования передавал бы всё :)
P.S. По поводу «почему C++» (
Ключевой момент тут такой: если не заниматься байтодрочерством, C++ из-за подобных недофич (чуть что — копируем! ну или не смогли понять жизненный цикл — тоже на всякий случай скопируем) будет работать не сильно быстрее остальных дефолтных языков, а то и медленнее и/или глючнее. Только если действительно понимать, что происходит, можно выжрать нетривиальный буст по производительности, и, если повезёт, не сильно потерять в безопасности. Но это если такая производительность действительно нужна. На мобилке она, за редкими исключениями, вряд ли нужна. В датацентре (если это не cuda) — уже более интересное распределение. Разница между десятью нодами и сотней нод в плане управления — колоссальна. Между сотней и тысячью — уже речь встаёт о дешевизне датацентра по сравнению с рабочим временем программиста.
Если C++ на вашем продукте позволяет обеспечить эту разницу в 10x, есть средства на программистов и время на их реализацию, почему бы и нет? У нас в MZ — есть. Компания зарабатывает несколько миллионов долларов в день. А в вашем НИИГиТ наверняка нет ни таких средств, ни таких требований к производительности, которые бы требовали кластера из более чем десятка машин, а их оптимизация явно встанет зарплатой программистов дороже, чем выгода от их сокращения.