Функции std::make_
в стандарте, например:
std::make_unique
и std::make_shared
std::make_tuple
std::make_from_tuple
все используются внутри инициализация круглых скобок вместо фигурных скобок .
Например, make_from_tuple
как представлено стандартный выбирает для возврата T(params...)
, а не T{params...}
.
В результате следующие недопустимы:
auto vec = std::make_from_tuple<std::vector<int>>(std::make_tuple());
auto arr = std::make_from_tuple<std::array<int, 2>>(std::make_tuple(9, 8));
^ создание std::array
из tuple
, как указано выше, недопустимо также с C ++ 20 , как p0960 - позволяет инициализировать агрегаты из списка значений в скобках становление частью C ++ 20 spe c не допускает такую инициализацию для std::array
, так как его внутренний тип T[size]
не может быть инициализирован из списка значений ( круглые скобки уже удаляются при инициализации std::array
).
В тех случаях, когда это работает, выбор инициализации скобок vs . фигурные скобки имеют значение:
auto vec2 = std::make_from_tuple<std::vector<int>>(std::make_tuple(2, 3));
// a vector with the values: {3, 3} surprise? :-)
(Выше, конечно, примеры игрушек . Поставляемый кортеж может быть предоставлен извне).
С curly_make_from_tuple
, например:
template<typename T, typename tuple_t>
constexpr auto curly_make_from_tuple(tuple_t&& tuple) {
constexpr auto get_T = [](auto&& ... x){ return T{std::forward<decltype(x)>(x) ... }; };
return std::apply(get_T, std::forward<tuple_t>(tuple));
}
, все вышеупомянутые случаи будут работать, так что можно утверждать естественнее:
auto arr = curly_make_from_tuple<std::array<int, 2>>(std::make_tuple(9, 8)); // {9, 8}
auto vec = curly_make_from_tuple<std::vector<int>>(std::make_tuple()); // {}
auto vec2 = curly_make_from_tuple<std::vector<int>>(std::make_tuple(2, 3)); // {2, 3}
Вопрос: почему стандарт выбрал инициализацию круглых скобок поверх фигурные скобки ?
Ссылки по теме:
Аналогичный вопрос, с точки зрения эффективности: Почему реализация make_tuple не возвращается через инициализацию скобок?
Приятное обсуждение и предложения по добавлению опции инициализации фигурных скобок для утилит `make_` .
Исходный документ, предлагающий make_from_tuple
, P0209r2 , кажется, чтобы обсудить две альтернативы T(params...)
и T{params...}
, возможно потому, что во всех аналогичных make_
служебных методах уже использовалась инициализация круглых скобок.