Представлять необязательный атрибут в качестве члена класса C ++ - PullRequest
0 голосов
/ 27 сентября 2018

Я генерирую код C ++ на основе схемы.Существуют сущности, и каждая сущность содержит атрибут (ы), причем каждый атрибут имеет соответствующий тип данных.Теперь проблема в том, что некоторые из этих атрибутов являются «необязательными», то есть они не обязательно должны быть частью объявления класса.Однако в C ++ что-то является либо членом класса, либо не членом класса, нет такого понятия, как «необязательный член данных».

Объекты будут именами классов, а атрибуты - членами классов.Я не уверен, как я могу представить атрибуты, помеченные как «необязательные» для существующих концепций C ++.

1 Ответ

0 голосов
/ 27 сентября 2018

Канонический ответ: std::optional.Это семантически точный способ выражения значения, которое может существовать или не существовать в модели.

При создании такой модели для каждого необязательного поля в схеме вы генерируете соответствующую запись std::optional в оболочке,Затем при десериализации вы можете использовать std::none, чтобы отметить отсутствующую запись, и при обращении к ней клиентский код должен проверить наличие фактического значения 1 .

Если ваши объекты большие, и вы хотите избежать ненужного хранения пустого пространства 2 , следующая альтернатива - std::unique_ptr.Недостатком является наличие семантики указателя, но в остальном он остается действительным инструментом для такого случая.

Если элементы очень динамические, например, возможный набор составляет десятки или сотни, нотипичное использование увидят лишь немногие, хранилище значений ключей (например, std::map) может быть лучшей идеей;тогда вы можете хранить только один тип значения.Это может быть немного смягчено с помощью std::variant, используемого в качестве типа значения карты, который дает вам одну из многих возможностей, или std::any, который может эффективно удерживать что угодно, в то же время теряя безопасность типов.

Решение будетв конечном итоге зависит от вашей точной модели и характеристик использования.


1 Если клиентский код ожидает T, а доступ к полю дает им optional<T>, этап развертываниябудет / должен проверить наличие фактического значения.Это основная причина использования optional.

2 sizeof(optional<S>) чаще всего будет sizeof(S) + 1, но может увеличиться из-за правил выравнивания. Производительность и память * В разделе 1039 * этой статьи это прекрасно показано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...