Рассмотрим следующий код, который компилируется в Clang, GCC и VS 2015 (онлайн-пример):
#include <utility>
class S
{
public:
S(int x) : i(x) { }
~S() { }
S(S&&) = default;
S(const S& ) = delete;
S& operator=(S&&) = delete;
S& operator=(const S&) = delete;
private:
int i;
};
S GetS()
{
// This is a contrived example with details elided. Assume
// there's a reason in the actual use case for returning via
// std::move.
return std::move( S(999) );
}
int main()
{
S tmp = GetS(); // <-- Assignment allowed even though assignment operator is deleted?
return 1;
}
Я не понимаю, почему линия
S tmp = GetS();
компилируется, выполняя конструктор перемещения вместо оператора присваивания перемещения.
Я знаю, что RVO позволяет исключать построение и присваивание в качестве оптимизации, но я так понимаю, что явное удаление оператора должно привести к сбою компиляции, если этот оператор явно используется в коде.
Есть ли в спецификации C++11 какой-либо пункт, который позволяет компилятору преобразовывать инициализацию присваивания в конструкцию копирования, даже если операторы присваивания для типа были явно удалены?