Секвенирование среди расширения вариативных
Для этого невариадического примера:
int     Func1();
double  Func2();
void    MyFunc( int, double );
int  main()
{
    MyFunc( Func1(), Func2() );
    //...
}
Не указано, вычисляется ли сначала Func1() или Func2(), просто то и другое должно быть сделано до вызова MyFunc().
Как эта последовательность работает с расширением вариадических аргументов?
template < typename Func, typename ...Args >
void  MyFunc2( Func &&f, Args&& ...a )
{
    int  b[] = { f( std::forward<Args>(a) )... };
    //...
}
Предположим, что f - это объект функции, который изменяет свое состояние после первого вызова.  Будет ли f вызываться по порядку для каждого сегмента a?  Другими словами, будет ли f вызываться по первому пункту в списке a, затем второй пункт, третий и т. д., вместо того, чтобы случайно пропустить расширенный список?  Есть ли то, что мы привыкли называть точками последовательности между каждым элементом?
1 ответ:
Да, заключенные в скобки списки инициализаторов гарантируют порядок вычисления слева направо, в то время как вызовы функций этого не делают. Так что
MyFunc2будет следовать правильно.Статья Википедии описывает это: https://en.wikipedia.org/wiki/Variadic_templates
Есть ли то, что мы привыкли называть точками последовательности между каждым элементом?Нет, хотя он использует знак запятой, это не оператор запятой.