Является ли подпись оператора пользовательского назначения =() вопросом, когда я просто хочу его отключить?

Мне нужно отключить оператор присваивания копии. Это будет работать:

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 
};