Почему стандартная предпочтительная инициализация круглых скобок для `make_ <something>`? - PullRequest
1 голос
/ 26 мая 2020

Функции 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_ служебных методах уже использовалась инициализация круглых скобок.

1 Ответ

1 голос
/ 27 мая 2020

Потому что было невозможно инициализировать структуру с помощью braced-init-list в C ++ 98.

Таким образом, для согласованности новые стандартные функции библиотеки использовали ту же форму инициализации, что и та, которая используется в STL.

Более того, он никогда не изменялся на инициализацию списка по соображениям совместимости: инициализация списка не обязательно имеет то же значение, что и эквивалентная форма инициализации в скобках.

...