ideas
ideas copied to clipboard
Решение проблемы релоцирования объектов
Вся суть проблемы с релоцированием объектов заключается в том, что компилятору неизвестно каким образом происходит мув и из кода невозможно узнать (помимо trivial мува) каково поведение типа.
Но если посмотреть на проблему шире, оказывается, что валидных стратегий реализации мув конструктора всего 4:
- memcpy (trivial move)
- exchange с дефолтным состоянием
- self reference сценарий
- у объекта вовсе нет мува, а есть только копирование(С++03 объект) ну или тип вообще не movable, но очевидно его и релоцировать нельзя Так вот, сейчас в С++ представлен только первый тип как = default и трейт is_trivially_move_constructible,
Я предлагаю
добавить сценарий 2 как стратегию поведения на муве и трейты для этого, например
Type(Type&&) = default; // то что сейчас, мув конструктор у всех филдов/базовых классов
Type(Type&&) = swap; // дефолтное конструирование + вызов swap через adl для всех филдов и базовых классов
То же самое можно сделать с оператором Type& operator=(Type&&) = swap; // типичная реализация мув оператора
и добавить трейт is_not_self_reference<Type> который будет давать true если у типа и рекурсивно у всех типов за ним нет нетривиальных мувов. Т.к. фактически нет никакого смысла делать нетривиальный мув при таких условиях
Это
- уберёт бойлерплейт
- позволит компилятору и контейнерам узнавать практически во всех случаях, что тип не селф референс
Более того, практически все дефолтные конструкторы и деструкторы можно сделать constexpr, даже у std::any такой конструктор. компилятор может "выдумать" объект и дефолтно его сконструировать, а потом разрушить и на компиляции узнать, что деструктор был noop.
Для этого я предлагаю ещё один трейт is_trivially_destructible_after_move
std::is_trivially_relocatable помоему направлен на решение тойже проблемы другим путем https://github.com/cplusplus/papers/issues/43
std::is_trivially_relocatable помоему направлен на решение тойже проблемы другим путем cplusplus/papers#43
я прекрасно знаю об этом и многих других пропозалах, их проблема в том, что они не помогают компилятору ничего вывести и не уменьшают количество нужного кода, а лишь увеличивают. Например, нужно будет аттрибутом или ещё как то помечать типы тривиальные для релоцирования, к тому же нет ничего что уже сейчас бы не было доступно, т.е. прямо сейчас вы можете сделать using relocatable = int; внутри типа, потом в алгоритмах это проверять. Это будет надёжнее аттрибута. Короче говоря усложнение языка без профитов
Моё предложение делает эту работу за программиста и позволяет старому коду стать лучше, иногда с минимальными изменениями типа = swap, позволит компилятору вовсе не генерировать мув конструкторы и т.д.
И если говорить про трейт is_trviially_destructible_after_move я считаю это первый шаг к тому чтобы статически доказывать семантические утверждения про типы, то чего так хотел Страуструп.