возвращаемый тип удалённой функции
От: B0FEE664  
Дата: 03.01.22 15:53
Оценка: 1 (1)
Легальна ли следующая декларация?:
class ALongClassName 
{
    inline auto operator = (const ALongClassName&) = delete;
};
И каждый день — без права на ошибку...
Re: возвращаемый тип удалённой функции
От: σ  
Дата: 03.01.22 16:04
Оценка: 6 (1) +1
BFE>Легальна ли следующая декларация?:
BFE>
class ALongClassName 
{
    inline auto operator = (const ALongClassName&) = delete;
};

Не знаю ничего, что бы её запрещало.
Re: возвращаемый тип удалённой функции
От: reversecode google
Дата: 03.01.22 16:12
Оценка:
inline бессмысленный
а auto избыточный
и оба в сигнатуре не берут участия

так что легально
Re: возвращаемый тип удалённой функции
От: BigBoss  
Дата: 09.01.22 08:28
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Легальна ли следующая декларация?:

BFE>
BFE>class ALongClassName 
BFE>{
BFE>    inline auto operator = (const ALongClassName&) = delete;
BFE>};
BFE>


Вопрос конечно интересный.
На первый взгляд нет, тип auto ниоткуда не выводится, а функции не могут различаться только типом возвращаемого значения.
На второй, при компиляции нет других вариантов для operator = (const ALongClassName&), компилятор генерирует copy assignment operator: If no user-defined copy assignment operators are provided for a class type (struct, class, or union), the compiler will always declare one as an inline public member of the class. This implicitly-declared copy assignment operator has the form T& T::operator=(const T&) if all of the following is true:
each direct base B of T has a copy assignment operator whose parameters are B or const B& or const volatile B&;
each non-static data member M of T of class type or array of class type has a copy assignment operator whose parameters are M or const M& or const volatile M&.
Затем именно этот оператор и удаляется, так что декларация легальна.
Re[2]: возвращаемый тип удалённой функции
От: Андрей Тарасевич Беларусь  
Дата: 09.01.22 16:35
Оценка:
Здравствуйте, BigBoss, Вы писали:
BB>Затем именно этот оператор и удаляется, так что декларация легальна.

Не ясно, о каком "затем" вы ведете речь.

Оператор, который явно объявлен пользователем как deleted, все равно является user-declared. Если в классе есть user-declared копирующий оператор присваивания, то компилятор не будет объявлять своего оператора присваивания вообще. Поэтому тут нечего удалять. Ни о каком "затем именно этот оператор и удаляется" речи не идет.
Best regards,
Андрей Тарасевич
Отредактировано 09.01.2022 17:22 Андрей Тарасевич . Предыдущая версия .
Re[3]: возвращаемый тип удалённой функции
От: BigBoss  
Дата: 12.01.22 00:17
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Здравствуйте, BigBoss, Вы писали:

BB>>Затем именно этот оператор и удаляется, так что декларация легальна.

АТ>Не ясно, о каком "затем" вы ведете речь.


АТ>Оператор, который явно объявлен пользователем как deleted, все равно является user-declared. Если в классе есть user-declared копирующий оператор присваивания, то компилятор не будет объявлять своего оператора присваивания вообще. Поэтому тут нечего удалять. Ни о каком "затем именно этот оператор и удаляется" речи не идет.


Позволю не согласиться. В данном случае удаляеится именно дефолтовый оперетор копирования.
Для проверки:

1. попытайтесь скомпилировать
ALongClassName a;
ALongClassName b;
a = b;

К примеру придётся добавить public:, но и это не спасёт.

2. Добавьте строчку inline int operator = (const ALongClassName&);
И auto operator = (const ALongClassName&) внезапно перестанет компилироваться.
Re[4]: возвращаемый тип удалённой функции
От: watchmaker  
Дата: 12.01.22 01:12
Оценка:
Здравствуйте, BigBoss, Вы писали:

BB>Здравствуйте, Андрей Тарасевич, Вы писали:


АТ>>Оператор, который явно объявлен пользователем как deleted, все равно является user-declared. Если в классе есть user-declared копирующий оператор присваивания, то компилятор не будет объявлять своего оператора присваивания вообще. Поэтому тут нечего удалять. Ни о каком "затем именно этот оператор и удаляется" речи не идет.


BB>Позволю не согласиться. В данном случае удаляеится именно дефолтовый оперетор копирования.


Что же тогда компиляторы единогласно говорят что его сигнатура не является сигнатурой "дефолтного оператора": https://godbolt.org/z/nEWe4znMe
class ALongClassName { 
    auto operator=(const ALongClassName&) = default; // compilation error: 'auto ALongClassName::operator =(const ALongClassName &)': is not a special member function or comparison operator

};
Так что удаляется не именно тот оператор присваивания, который бы сгенерировал компилятор при отсутствии user-declared и при прочих условиях.


А прикол с auto ... = delete тут в немного в другом: можно в декларации не указывать возвращаемый тип сразу, если определение встретится до использования:
auto foo();  // декларация функции валидная, но до определения ей пользоваться нельзя

...
auto foo() { return 4; } 
// а теперь можно

Но = delete сразу определяет функцию или метод как удалённый и до вывода типа auto дело не доходит.
Re[4]: возвращаемый тип удалённой функции
От: Андрей Тарасевич Беларусь  
Дата: 12.01.22 01:23
Оценка: +1
Здравствуйте, BigBoss, Вы писали:
BB>Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>>Здравствуйте, BigBoss, Вы писали:
BB>>>Затем именно этот оператор и удаляется, так что декларация легальна.

АТ>>Не ясно, о каком "затем" вы ведете речь.


АТ>>Оператор, который явно объявлен пользователем как deleted, все равно является user-declared. Если в классе есть user-declared копирующий оператор присваивания, то компилятор не будет объявлять своего оператора присваивания вообще. Поэтому тут нечего удалять. Ни о каком "затем именно этот оператор и удаляется" речи не идет.


BB>Позволю не согласиться. В данном случае удаляеится именно дефолтовый оперетор копирования.


У нас чисто схоластически-терминологическое несогласие. Никто, разумеется, не спорит с тем, что в таком случае у класса не будет копирующего оператора присваивания. Это верно — его не будет. И приведенный вам код не будет компилироваться именно по этой причине.

Несогласие только в том, как работает внутренняя логика языка С++, приведшая к отсутствию этого оператора. Вы как-будто утверждаете, что компилятор сначала предоставляет свой компиляторный копирующий оператор присваивания, а затем мы его подавляем/удаляем именно вот через это `= delete`. Я ссылаюсь именно на ваше слово "затем" в ваших словах, процитированных выше.

Но на самом деле логика языка С++ работает как раз таки наоборот, в противоположном порядке:

Сначала компилятор проверяет, не объявил ли пользователь своего копирующего оператора присваивания. При этом в роли копирующего оператора присваивания может выступать целый зоопарк вариаций: с параметрами типа `X`, `X &`, `const X &`, `volatile X &` или `const volatile X &`.

И только если пользователь не объявил своего копирующего оператора присваивания, тогда (и только тогда) компилятор неявно предоставляет свою версию.

Именно в таком порядке: сначала ищется пользовательский оператор, и только потом (и только если пользовательского не найдено) объявляется компиляторный.

В данном примере пользовательский оператор присутствует. Мы его явно объявили и компилятор его найдет. Тот факт, что наш пользовательский оператор объявлен как `= delete` никак не отменяет того факта, что объявление пользовательского оператора в классе присутствует. То есть все равно считается, что в данном случае пользователь явно объявил копирующий оператор присваивания.

В такой ситуации компилятор вообще не будет предоставлять свой неявный копирующий оператор присваивания.

То есть это не мы удалили компиляторный копирующий оператор присваивания своим `= delete`, а его и не было никогда вообще. Мы, условно говоря, "влезли раньше".

Другими словами, "удаление" компиляторного копирующего оператора присваивания произошло совсем не из-за `= delete`, а просто уже потому, что мы явно объявили метод с сигнатурой `operator =(const X&)`. Этого уже достаточно для того, что "удалить" компиляторный оператор.
Best regards,
Андрей Тарасевич
Отредактировано 12.01.2022 1:27 Андрей Тарасевич . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.