MyClass obj = MyClass (); означает ли 'MyClass ()' временный объект здесь?

учитывая случай, когда не задействовано копирование-elision (pre C++17).

из cppreference (опять же, предположим, C++14):

временные объекты создаются в следующих ситуациях:

  • привязка ссылки к prvalue
  • возврат значения prvalue из функции
  • преобразование, которое создает prvalue
  • лямбда-выражение
  • copy-инициализация, которая требует преобразование инициализатора
  • list-инициализация, которая создает std:: initializer_list
  • ссылка-инициализация на другой, но конвертируемый тип или на битовое поле.

все случаи, кроме первого, кажутся неуместными, первый, похоже, означает привязку ссылок в стиле C++(int &&x = 5; кстати, я не понимаю в таких обстоятельствах утверждение, что временные уничтожаются в конце полного выражения..., этот объект 5 имеет в виду, похоже, не уничтожается в конце утверждения).

кстати, есть ли разница между MyClass() и 4 на int x = 4; (или 2 + 2 на int x = 2 + 2;)? Например, может быть, я ошибаюсь, и первый из них относится к временный объект, а два других - нет...

1 ответов


стандарт C++14[1] говорит в 12.2 относительно временных объектов ([class.temporary]):

временные типы классов создаются в различных контекстах: привязка ссылки к prvalue ([...]), возвращающийся a prvalue ([...]), преобразование, создающее значение prvalue ([...], 5.4), исключение ([...]), и в некоторых инициализациях ([...]).

на MyClass obj = MyClass();, MyClass() является явным преобразованием типа в функциональной нотации, поэтому оно является временным объект, потому что он попадает под "преобразование, которое создает prvalue".

Это не относится к 4 на int x = 4; потому что правило относится к "типам классов", но int это "фундаментальными".

дополнительно 8.5 инициализаторы ([dcl.init]) определяет семантику инициализаторов неклассового типа в предложении (17.8) как

в противном случае начальным значением инициализируемого объекта является (возможно, преобразованное) значение инициализатора выражение. [...]

в то время как для типов классов вызываются (копировать) конструкторы. Таким образом, вам нужен (временный) объект для копирования из типов классов, но не для "других" типов.

[1]: на самом деле N4296, но это не должно иметь значения