Почему общедоступный конструктор копирования требуется при назначении временного возвращаемого объекта для ссылки?
Рассмотрим следующий код:
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, это поведение исчезло, и больше копирование не производится.