Информация об изменениях

Сообщение Re[4]: возвращаемый тип удалённой функции от 12.01.2022 1:23

Изменено 12.01.2022 1:27 Андрей Тарасевич

Re[4]: возвращаемый тип удалённой функции
Здравствуйте, BigBoss, Вы писали:
BB>Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>>Здравствуйте, BigBoss, Вы писали:
BB>>>Затем именно этот оператор и удаляется, так что декларация легальна.

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


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


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


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

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

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

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

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

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

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

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

То есть это не мы удалили компиляторный копирующий оператор присваивания своим `= delete`, а его и не было никогда вообще. Мы, условно говоря, "влезли раньше".
Re[4]: возвращаемый тип удалённой функции
Здравствуйте, 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&)`. Этого уже достаточно для того, что "удалить" компиляторный оператор.