Closed Neargye closed 3 years ago
Andrey Davydov 4 апреля 2019, 16:09 На этом сайте предлагалось как минимум трижды:
https://stdcpp.ru/proposals/ca25e663-71b4-45da-a8ab-9ed7deb17c6d
https://stdcpp.ru/proposals/b02ce2fb-5e59-4f15-b21c-a2cb8e25aaa0
https://stdcpp.ru/proposals/b41bac7b-f618-4ae0-b0fa-c3744ba26b9b
Актуальный proposal: http://wg21.link/p0847
Закрыто как дубликат #148
Перенос предложения: голоса +3, -2 Автор идеи: xjossy
Формулировка проблемы
Сейчас приходится дублировать код при наличии const и не-const версии одного метода в классе. Типичный пример - геттер:
Если логика этой функции более сложна, то возникает нежелательное дублирование кода. Элегантного метода решения на данный момент не существует. Скотт Мейерс рекомендует использовать const_cast, что не способствует читаемости и надёжности кода. В современном Стандарте его подход реализуется так:
Также возможно решение с шаблонной функцией, которая обязана быть статической (чтобы избежать необходимости указания квалификатора). Она также может быть настроена на нежелательные типы (если это специально не исключено). Но даже этот пример не решает проблемы дублирования сигнатуры функции:
Предлагаемое решение
Добавить новый тип неклассовых параметров шаблона - qualifier, который может применяться к функции. Пример кода:
Это полностью решит проблему.
Минусы этого решения:
Такое решение позволит обойтись без дополнительных ключевых слов.
Необходимо проработать использования volatile-квалификатора, так как пример выше подразумевает наличие volatile и const volatile специализации. Не ясно, нужны ли они. В качестве решения предлагается возможность ограничивать квалификатор только одним введением дополнительных типов: std::const_qualifier, std::volatile_qualifier.
Необходимо убедиться в том, что добавление идентификатора на местро квалификатора не вызовет синтаксических неоднозначностей.
С учётом всех этих замечаний, решение могло бы быть таким:
Заметка о реализации
Наиболее существенной проблемой в реализации будет скорее всего вывод значения квалификатора, как шаблонного параметра. Это можно разрешить, так как thiscall функция содержит неявный параметр this, из типа которого могут быть выведены квалификаторы (даже в рамках современного Стандарта).
Допольнительная мотивация - ещё один пример применения
Рассмотрим class SerializableScheme, который позволяет сериалиовывать и десериализовывать некоторое количество данных. Этот класс может использовать указатели, чтобы сразу помещать данные в нужное место. Его интерфейс может быть таким:
Его использование может быть таким:
Проблема в том, что с помощью такого сериализатора не получится сохранить констанстный объект A.
Решение - сделать getScheme() константным методом не сработает, т. к. для объект, полученный из констрантного объекта A не сможет реализовать метод load() (без применения const_cast).
Остаётся только такое решение:
Если объект A сложнее, то дублирование кода будет более существенным.
С введением параметра квалификатора решение было бы таким:
Спасибо всем, кто дочитал до конца, надеюсь, идея понравилась