тривиально конструируемый по умолчанию std:: optional и std:: variant

Можно ли спроектировать std::optional (в настоящее время std::experimental::optional) таким образом, чтобы для тривиально конструируемого по умолчанию типа T соответствующий std::optional< T > также был тривиально конструируемым по умолчанию?

Тот же вопрос относительно std::variant и его интегрального дискриминатора.

Мой собственный ответ: «Нет, это не может быть спроектировано таким образом, потому что значение его интегрального дискриминатора, полученное во время инициализации по умолчанию, будет неопределенным, если объект имеет автоматическую продолжительность хранения или если он reinterpret_cast-ed из ненулевой инициализированной памяти ." Требование к пользователю выполнять инициализацию значения каждый раз недопустимо, на мой взгляд.


person Tomilov Anatoliy    schedule 03.12.2015    source источник
comment
Могу я спросить вас взамен, почему это важно для вас? Я могу представить, почему вы не хотите, чтобы вас тривиально копировали. Но почему тривиально-по-умолчанию-конструируемым? Что это покупает вам?   -  person Andrzej    schedule 03.12.2015
comment
@Andrzej Контейнер (например, optional или variant) должен быть как можно более универсальным, не так ли? Я пытаюсь спроектировать variant для constexpr. И в настоящее время он имеет выше способности. Но я думаю, может, мне стоит это отрицать?   -  person Tomilov Anatoliy    schedule 03.12.2015
comment
@Andrzej В конце концов я нашел ошибку в моем variant. Инициализированные по умолчанию объекты ведут себя по-разному во время компиляции (constexpr) и во время выполнения. Затем я прочитал об инициализации. И обнаружил, что есть UB для использования моего инициализированного по умолчанию variant в стеке.   -  person Tomilov Anatoliy    schedule 03.12.2015


Ответы (2)


Ваш ответ правильный: нельзя. Спецификация требует, чтобы его «флаг инициализации» был установлен на false при построении по умолчанию.

person Andrzej    schedule 03.12.2015

Как вы сами объяснили, вы не можете реализовать std::Optional таким образом, потому что вы изменили бы его семантику (is_tribuly_default_constructible является частью интерфейса класса).

Однако, если вам по какой-то причине требуется эта семантика в вашем коде, нет причин, по которым вы не могли бы реализовать очень похожий необязательный класс, который тривиально конструируется по умолчанию. Затем, при использовании, просто инициализируйте его нулем через {} и, если это то, что вы хотите, обработайте ноль как истину в операторе bool.

person MikeMB    schedule 03.12.2015