Является ли подпись оператора пользовательского назначения =() вопросом, когда я просто хочу его отключить?
Мне нужно отключить оператор присваивания копии. Это будет работать:
A& operator=(const A&);
Будет ли он работать, если я не укажу точные параметры для operator=
?
Я имею в виду что-то вроде этого:
void operator=(void);
Возвращаемое значение верно, я могу писать все, что захочу, но как насчет типа параметра?
Будет ли это переопределять стандартный operator=
для класса?
Ответы
Ответ 1
Из 12.8p17 стандартного черновика С++:
Пользовательский оператор присваивания копий X::operator=
- это нестатическая неклассическая функция-член класса X
с ровно одним параметром типа X
, X&
, const X&
, volatile X&
или const volatile X&
.
Я думаю, это ответ лучше, чем любой другой тестовый или примерный код.
Обратите внимание, что что-то подобное применимо также к оператору присваивания перемещения, см. 12.8p19:
Пользовательский оператор присваивания оператора X:: operator = - нестатическая нематричная функция-член класса X с точно одним параметром типа X & &, const X & &, volatile X && &, или const volatile X & &.
Они также подтверждают, что, как вы догадались, возвращаемые типы значений не имеют значения.
Ответ 2
Здесь могут быть разные типы назначений. Компилятор потенциально генерирует только назначение копирования и назначение переноса. Они генерируются, если нет назначения копирования/перемещения. Таким образом, если вы хотите отключить копирование и/или перемещение назначения, тип аргумента имеет значение, хотя есть определенная гибкость, поскольку назначение копирования может иметь разные типы аргументов. Тип возврата не имеет значения.
class A {
public:
void operator=() = delete; // not legal: assignment takes exactly one argument
void operator=(A) = delete; // OK: copy assignment disabled
void operator=(A&) = delete; // OK: copy assignment disabled
void operator=(A const&) = delete; // OK: copy assignment disabled
void operator=(A&&) = delete; // OK: move assignment disabled
};
Существуют также варианты, заменяющие const
на volatile
или const volatile
, которые квалифицируются как назначения копирования/перемещения. Когда вы отключите назначение копии, автоматическая генерация назначения перемещения также будет отключена. Если вы отключите назначение переноса, я думаю, что назначение копии все равно будет сгенерировано. Если вы отключите что-либо, что не может быть копией или перемещением, копирование/перемещение все еще будут сгенерированы.
Ответ 3
Это точное определение оператора, объявленного пользователем, из текущего стандарта (§ 12.8 стр. 17):
Оператор присваивания, указанный пользователем X::operator=
, является нестационарным не-шаблонная функция члена class X
с ровно одним параметром тип X, X&, const X&, volatile X&
или const volatile X&
.
Примечания:
- Перегруженный оператор присваивания должен быть объявлен как один
параметр; см. 13.5.3.
- Более чем одна форма оператора присваивания копии может быть объявлена для класса.
- Если класс X имеет только оператор присваивания копии с параметром типа X &, выражение типа const X не может быть назначено объекту типа X.
Пример:
struct X {
X();
X& operator=(X&);
};
const X cx;
X x;
void f() {
x = cx; // error: X::operator=(X&) cannot assign cx into x
}
Кроме того, пожалуйста, используйте удалить из стандарта С++ 11.
Теперь вы можете установить функции как по умолчанию, так и по умолчанию.
Теперь вы можете прямо написать, что вы хотите отключить копирование.
class A {
A(const A&) = delete;
A& operator=(const A&) = delete; // Disallow copying
};
Вы также можете явно сообщить компилятору, что хотите получить копию экземпляра по умолчанию. Таким образом, вы можете предоставить настраиваемый конструктор по умолчанию и по-прежнему получать версии компилятора от других компиляторов по умолчанию.
class B {
B(const Y&) = default;
B& operator=(const B&) = default; // default copy
};