Open apolukhin opened 3 years ago
Андрей Руссков, 1 июня 2018, 7:07 поправка: "в случае доступности копирующих операторов присваивания"
languagelawyer, 1 июня 2018, 11:46 Предлагается в неявном операторе присваивания делать placement new с конструктором копирования поверх константного члена? После такого этим объектом, или по крайней мере константным подобъектом, нельзя будет пользоваться без std::launder. И std::launder нужен не в том месте, как написано у автора предложения.
Похоже, предложение родилось из неправильного понимания std::launder.
Андрей Руссков, 1 июня 2018, 12:43 languagelawyer, launder тут ни при чем, ровно как и placement new. Предложение призвано упростить работу со структурами/классами с const members. Например, есть у нас простая запись о сотруднике:
struct Record {
const int id {0};
const Date dateOfBirth {};
string name;
Position position;
// ...
};
предполагается, что в процессе работы приложения у сотрудника могут измениться имя (вдруг поменяет) и должность, но не могут измениться дата рождения и id записи. Однако при таком подходе одну запись нельзя заменять другой, что сильно ограничивает возможность их применения:
vector<Record> employees;
employees.push_back({id, date, name, position, ...}); // Легально
sort(employees.begin(), employees.end(), dateLess); // Ошибка
employees.erase(it); // Ошибка
partition(employees.begin(), employees.end(), [](auto &r) { return r.sex == Male; }); // Ошибка
Pavel Verutin, 11 июня 2018, 18:40 А если есть такая структура:
struct TestStruct
{
TestStruct(int someInt = 0)
: m_someInt(someInt), m_pInt(&m_someInt) {}
TestStruct(TestStruct const & other)
: m_someInt(other.m_someInt), m_pInt(&m_someInt) {}
private:
int m_someInt;
int * const m_pInt;
};
что должно произойти с указателем при вызове оператора присваивания?
Андрей Руссков, 13 июня 2018, 5:59 Pavel Verutin, этот случай не попадает под условия генерации неявного оператора присваивания
languagelawyer, 14 июня 2018, 1:43
Предлагаю: не удалять неявный оператор копирующего присваивания из-за наличия const полей в случае доступности копирующих операторов присваивания этих полей.
В случае константных полей-классов неявный оператор и так не удаляется, если копирующий оператор для поля можно вызвать: https://wandbox.org/permlink/J5qKwNxMPEYwwF8F Правда, он для этого должен быть с const-квалификатором, что довольно бессмысленно.
Если есть в классе есть "a non-static data member of const non-class type", то тогда да, неявный оператор определяется удалённым (http://eel.is/c++draft/class.copy.assign#7.2). Только о какой "доступности" копирующего оператора присваивания может идти речь, например, для const int
?
WPMGPRoSToTeMa, 20 июня 2018, 18:05 Я думаю такую структуру проще обернуть в std::variant с одним типом.
Перенос предложения: голоса +2, -3 Автор идеи: Андрей Руссков
Убрать ограничение на изменяемость полей для копирующего оператора присваивания
Сейчас для классов с const полями неявный оператор присваивания не генерируется, т.к. он эквивалентен поэлементному присваиванию полей, недоступному в случае const. Пример:
Однако, при таком подходе теряется сама суть ограничения const для поля класса - неизменяемость поля выливается в незаменяемость экземпляра. В таком случае легально заменить экземпляр можно используя пару из деструктора и copy-конструктора:
что куда хуже отражает суть намерений программиста.
Предлагаю: не удалять неявный оператор копирующего присваивания из-за наличия const полей в случае доступности копирующих конструкторов этих полей.
Влияние на существующий код: может поменяться поведение для кода, зависящего от свойства is_copy_assignable.