Почему общедоступный конструктор копирования требуется при назначении временного возвращаемого объекта для ссылки?

Рассмотрим следующий код:

class MyClass
{
    MyClass()
    {
        x = 0;
    }
    MyClass(const MyClass&)
    {
        x = 1;
    }
public:
    int x;
    MyClass(MyClass&&)
    {
        x = 2;
    }
    static const MyClass f()
    {
        return MyClass();
    }
};

int main()
{
    const MyClass& p = MyClass::f();
    return 0;
}

Этот код не компилируется на VC++ 2010.

error C2248: 'MyClass::MyClass: cannot access private member declared in class 'MyClass'

Я считаю, что это как-то связано с RVO, но я бы хотел лучше понять, что он делает. Я не вижу причин для вызова конструктора копирования.

Вот что я ожидал:

  • Введите f()
  • Вызов конструктора по умолчанию
  • Вызовите конструктор перемещения, чтобы вернуть объект (возможно, оптимизированный с помощью RVO)
  • Присвоить объект временного возврата для ссылки p

Фактически, если я сделаю конструктор копирования общедоступным, он скомпилируется и будет работать именно так. Конструктор копирования никогда не вызывается. Конечное значение x равно 0.

1 ответ

Решение

Это связано с правилами C++03. В C++03, изначально присваивая временную ссылку, можно скопировать временную.

Начиная с C++11, это поведение исчезло, и больше копирование не производится.

Другие вопросы по тегам