Рассмотрим следующий код:
#include <iostream>
struct Thing
{
Thing(void) {std::cout << __PRETTY_FUNCTION__ << std::endl;}
Thing(Thing const &) = delete;
Thing(Thing &&) = delete;
Thing & operator =(Thing const &) = delete;
Thing & operator =(Thing &&) = delete;
};
int main()
{
Thing thing{Thing{}};
}
Я ожидаю, что оператор Thing thing{Thing{}}; будет означать создание временного объекта класса Thing с использованием конструктора по умолчанию и создание объекта thing класса Thing с использованием конструктора перемещения с только что созданным временным объектом в качестве аргумента. И я ожидаю, что эта программа будет считаться плохо сформированной, потому что она содержит вызов конструктора удаленного перемещения, даже если он потенциально может быть опущен. Раздел стандарта class.copy.elision, похоже, тоже требует этого:
выбранный конструктор должен быть доступен, даже если вызов отклонен
Однако gcc 7.2 (и clang 4 тоже, но не VS2017, который все еще не поддерживает гарантированное исключение копирования) будет просто скомпилировать этот код, исключив перемещение вызов конструктора.
Какое поведение было бы правильным в этом случае?
Thing thing{f()};, гдеf()возвращаетThing? - person Bo Persson   schedule 06.09.2017Thing thing{f()};будет означать вызов конструктора перемещения с временным, возвращаемымf()вызовом аргумента. Мы надеемся, что этого удастся избежать накладных расходов на создание временных файлов. - person user7860670   schedule 06.09.2017T(T(T()))сворачивается в()или что конструктор копирования / перемещения не выбран при разрешении перегрузки. - person Language Lawyer   schedule 18.06.2020