The arguments passed to function parameters aren't always temporary. They are only temporary in a special case:
When an object of class type X
is passed to or returned from a function, if X
has at least one eligible copy or move constructor ([special]), each such constructor is trivial, and the destructor of X
is either trivial or deleted, implementations are permitted to create a temporary object to hold the function parameter or result object.
The temporary object is constructed from the function argument or return value, respectively, and the function's parameter or return object is initialized as if by using the eligible trivial constructor to copy the temporary (even if that constructor is inaccessible or would not be selected by overload resolution to perform a copy or move of the object).
[Note 4: This latitude is granted to allow objects of class type to be passed to or returned from functions in registers.
— end note]
- [class.temporary] p3
Note that the condition is quite complicated here, and this is deliberate. Instead of saying that all trivially copyable types are passed as a temporary object, the condition ignores the copy/move assignment operators and mirrors the requirement of "ABI-triviality" in the System-V ABI, i.e. the requirements for pass-by-register.
Outside of this special case, function parameter objects are not temporary objects. One important distinction is that temporary objects are always destroyed at the end of the surrounding full-expression ([class.temporary] p4), but function parameter objects can be destroyed by the callee ([expr.call] p6).
Note that this paragraph states that the function parameter object isn't the temporary object but a trivial copy of it, and p7 suggests that the function parameter object itself could be temporary. I believe this to be an editorial mistake in p7.
for(auto x: {A{std::string{"abc"}}, A{std::string{"def"}}})
, the lifetime of the twoA
objects are extended to the end of the for loop, however the lifetimes forstd::string{"abc"}
andstd::string{"def"}
themselves are not extended. (This is a special case where the "function" is the constructor call, but it applies to other functions as well, for example,for(auto x:{makeA(std::string{"abc"}), makeA(std::string{"def"})})
) – DupeA
's constructor it is impossible to tell whether thestring
objects are function parameter objects. If they are, because the constructor takesstd::string
by-value, then yes, I think those are not supposed to be extended, but I think that "other than a function parameter object" wouldn't affect that because these objects aren't temporary objects to begin with. – Onanismprvalue
s that haven't materialized under the new lifetime rule updated after C++17, and therefore are not temporary objects? OK I think that makes sense. – Dupe