7
votes

Considering the case where no copy-elision is involved (pre C++17).

From cppreference (again, suppose C++14):

Temporary objects are created in the following situations:

  • binding a reference to a prvalue
  • returning a prvalue from a function
  • conversion that creates a prvalue
  • lambda expression
  • copy-initialization that requires conversion of the initializer
  • list-initialization that constructs an std::initializer_list
  • reference-initialization to a different but convertible type or to a bitfield.

All the cases except the first one seem irrelevant, the first one seems to mean C++-style reference binding (int &&x = 5; BTW I don't understand in such circumstance the statement that temporaries are destroyed at the end of the full-expression..., the object 5 is referring to doesn't seem to be destroyed at the end of the statement).

So, as I understood, the notion of a temporary object only includes those who are guaranteed to be stored (which is not the case in my situation due to possible elision). Am I correct? Or else what do I misunderstand here?

BTW is there any difference between MyClass() and 4 in int x = 4; (or 2 + 2 in int x = 2 + 2;)? Like maybe I'm incorrect and the first one DOES refer to a temporary object while the other two do not...

1
It's counted under the "conversion that creates a prvalue" case. (Yes, it doesn't look like a conversion, but the standard groups T(), T(1), and T(1,2) together.)T.C.
@T.C. so is such thing a temporary only for MyClass() case then? Not for the 4 I proposed as an example? Then what's the rationale for such difference? Maybe you could create an answer?.. Considering you seem to contradict the already existing one..ledonter
Wouldn't 4 still be covered by "conversion that creates a prvalue"? In this case it is conversion from integer literal, to a prvalue integer.Nir Friedman
@NirFriedman is there any difference between those? I thought 'integer literal' is exactly one of the cases for an integer prvalue.. Again from cppreference: The following expressions are prvalue expressions: a literal (except for string literal), such as 42, true or nullptr;ledonter

1 Answers

1
votes

The C++14 standard[1] says in 12.2 regarding Temporary objects ([class.temporary]):

Temporaries of class type are created in various contexts: binding a reference to a prvalue ([...]), returning a prvalue ([...]), a conversion that creates a prvalue ([...], 5.4), throwing an exception ([...]), and in some initializations ([...]).

In MyClass obj = MyClass();, MyClass() is a Explicit type conversion in functional notation, so it is a temporary object because it falls under "conversion that creates a prvalue".

This does not apply for the 4 in int x = 4; because the rule refers to "class types" but int is a "fundamental type".

Additionally 8.5 Initializers ([dcl.init]) defines the semantics of non-class type initializers in clause (17.8) as

Otherwise, the initial value of the object being initialized is the (possibly converted) value of the initializer expression. [...]

while for class types, (copy) constructors are invoked. So you need a (temporary) object to copy from for class types, but not for "other" types.

[1]: actually N4296, but that shouldn't make a difference