Можно ли выбросить объекты с частными конструкторами копирования?
Я столкнулся с проблемой исключения, которая мне непонятна. В С++, когда объект бросается, он сначала копируется во временный объект, а затем временный объект передается в код catch. Копия включает использование конструктора экземпляров класса объектов. AFAIK, это означает, что если класс имеет частный конструктор копирования, он не может использоваться как исключение. Однако в VS2010 следующий код компилируется и запускается:
class Except
{
Except(const Except& other) { i = 2; }
public:
int i;
Except() : i(1) {}
};
int main()
{
try
{
Except ex1;
throw ex1; // private copy constructor is invoked
}
catch (Except& ex2)
{
assert(ex2.i == 2); // assert doesn't yell - ex2.i is indeed 2
}
return 0;
}
Является ли это законным?
Ответы
Ответ 1
Это не легально. Стандарт 15.1/5
Если использование временного объекта можно устранить без изменения значение программы, за исключением выполнения конструкторов и деструкторы, связанные с использованием временного объекта (12.2), то исключение в обработчике можно инициализировать напрямую с аргументом выражения throw. Когда брошенный объект является объект класса и конструктор копирования, используемый для инициализации временная копия недоступна, программа плохо сформирована (даже если временный объект в противном случае можно было бы исключить). Аналогично, если деструктор для этого объекта недоступен, программа (даже если временным объектом в противном случае может быть устранена).
Ответ 2
Нет, это не так.
15.1.5 Когда брошенный объект является объектом класса, конструктор copy/move и деструктор должны быть доступны, даже если операция копирования/перемещения завершена