Секвенирование среди расширения вариативных
Для этого невариадического примера:
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
Есть ли то, что мы привыкли называть точками последовательности между каждым элементом?Нет, хотя он использует знак запятой, это не оператор запятой.