Почему операции в потоке выполняются в обратном порядке?
Экспериментировал с шаблонами и наткнулся на неожиданный порядок выполнения операций в потоке.
#include <iostream>
using namespace std;
template <class T>
int A(T a) {
static int t = static_cast<int>(a);
return t;
}
int main()
{
cout << A(5) << " " << A(6) << " " << A(7.2) << " " << A(7) << " " << A(2.8);
return 0;
}
я ожидал получить
5 5 7 5 7
но получил
7 7 2 7 2
Очевидно что функции выполнялись не в том порядке, в котором я ожидал, но почему именно так?
Ответы (2 шт):
Порядок вычисления аргументов функции не специфицирован. Например, для функции void f(int i, int j) при вызове с передачей в вызов других функций для порождения значений i и j, т.е.:
f(g(), k());
Нет гарантии того, что сначала будет вызвана g(), а только потом k().
Ровно то же самое происходит в вашем случае. Порядок вывода задаётся << как слева направо, однако сам вызов функций, которые порождают значения для вызова - неспецифицирован. При условии наличия состояния (статическая переменная внутри) функции это и приводит к такому, на первый взгляд, странному поведению.
Начиная с C++17 это исправлено (именно для << и >>), и ваш код в нем будет работать правильно.
Все из-за static. Как вы знаете статическая-переменная инициализируеться один раз. Второй раз - нет(остаеться предидущее значение). Компилятор создает 2 функции(одна с параметром double другая с параметром int).
То есть cout << A(5); это мы первый раз вызываем int-функцию и статическая переменная инициализируеться 5. Выводим на екран.
А второй раз вызвали - ту же самую функцию с интом-параметром! А статическая переменная уже была проиницализирована поэтому пропускаем присвоение нового числа и выводим старую пятерку!
cout << " " << A(7.2);
Вот это совсем другая double-функция и мы даем значение 7. И тд.
С потоком выполнения все ОК