c ++ 11 — массив инициализации оценочного порядка в переполнении стека

Мне нравятся шаблоны с ++ 11 variadic, поэтому я часто пишу с ними небольшие коды.

Смотрите этот пример:

#include <cstdio>
#include <type_traits>
#include <vector>

template< typename ... T >
auto make_vector(T ... t ) -> std::vector< typename std::common_type<T...>::type >
{
std::vector< typename  std::common_type<T...>::type > v;
v.reserve( sizeof...(T) );

using list = int[];
(void)list{ 0, ( (void)v.push_back(std::move(t)) ,0)... };
//                |/ / / /
//                --------
//                 \-- How are evaluated v.push_back()s, sequentially or arbitrary ?
return v;
}

int main()
{
auto v = make_vector(2, 3.0, 'a', 7UL );

for(auto e : v )
printf("%.2lf ", e);

printf("\n");

}

Вопрос: Является ли порядок вычисления инициализации массива последовательным или произвольным (или реализация определяется неопределенным поведением)?

Если make_vector неправильно, как мне исправить это?

9

Решение

Они оцениваются последовательно. C ++ 11 § 8.5.4 [dcl.init.list] параграф 4:

В пределах инициализатора-лист из приготовился-INIT-лист, инициализатора-статьи, включая любые, которые являются результатом пакета
Разложения (14.5.3) оцениваются в порядке их появления.

При условии vector имеет initializer_list конструктор, вы можете упростить вашу функцию:

template <typename ... T>
auto make_vector(T ... t) ->
std::vector< typename std::common_type<T...>::type >
{
return { static_cast<typename std::common_type<T...>::type>(t)... };
}

и не нужно беспокоиться о загадочной семантике инициализации;)

12

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

Других решений пока нет …