Я хотел бы перенести следующий код на C ++ 11:
template<unsigned i>
static void bar() { /* some code with compile-time optimizations for each value i */ }
template <unsigned... I>
void f()
{
((bar<I>()),...);
}
Порядок вызова 'bar' для каждого значения пакета параметров, который я важен, - который я считаю работает в реализации C ++ 17 выше, потому что выражение сгиба использует оператор запятой.
Сначала я использовал явно рекурсивную реализацию:
template <unsigned... I>
typename std::enable_if<sizeof...(I) == 0>::type g() {}
template <unsigned head, unsigned... I>
void g()
{
bar<head>();
g<I...>();
}
, которая, кажется, работает, но требует двух реализаций для g (). Пытаясь перейти к одной функции, я прочитал, что расширение пакета произойдет в make_tuple, и подумал, что это сработает:
template<unsigned... I>
static void h1()
{
std::make_tuple( (bar<I>(), 0)... );
}
к сожалению, это не обеспечит никакой гарантии порядка выполнения - фактически с g cc порядок выполнения в точности обратный. В качестве альтернативы я мог бы использовать список фигурных скобок:
template<unsigned... I>
static void h2()
{
using expand = int[];
expand{ 0, ( bar<I>(), 0) ... };
}
Кажется, это сохраняет порядок с g cc, но я не мог понять, является ли это только совпадением.
Итак, конкретные c вопросы:
- гарантирует ли реализация h2 правильный порядок выполнения?
- есть ли альтернативные реализации, которые я пропустил?