Поскольку существует конструктор, который может принимать аргумент, передаваемый в функцию F (), компилятор создает объект на лету, прежде чем поместить аргументы в стек. Как можно увидеть в разборке ниже. буквенные числа по умолчанию обрабатываются как целые числа, поэтому возможна конверсия.
001115C5 call implicit_t::implicit_t (11112Ch)
001115CA mov dword ptr [ebp-4],0
001115D1 mov esi,esp
001115D3 mov eax,dword ptr [__imp_std::endl (11A308h)]
001115D8 push eax
001115D9 lea ecx,[ebp-0D4h]
001115DF push ecx
001115E0 call f (111113h)
Ваш временный объект висит до тех пор, пока выражение не будет полностью оценено. это может стать более очевидным, если вы добавите еще один вызов к вашей функции.
int main()
{
std::cout << f(42) << std::endl;
std::cout <<f(80) << std::endl;
return 0;
}
Который имеет выход
ctor
42
dtor
ctor
80
dtor