Каково обоснование реализации boost::none_t?

Boost.Optional использует фиктивный тип, позволяющий создавать неинициализированные экземпляры boost::optional<T>, Этот тип называется none_tи экземпляр none для удобства уже определен в заголовке, что позволяет нам писать такой код:

boost::optional<int> uninitialized(boost::none);

Глядя на определение none_tЯ заметил, что на самом деле это typedef, соответствующий указателю на член некоторой фиктивной структуры:

namespace boost {

namespace detail { struct none_helper{}; }

typedef int detail::none_helper::*none_t ;

none_t const none = (static_cast<none_t>(0)) ;

} // namespace boost

Каковы преимущества использования такого замысловатого определения типа по сравнению с простой пустой структурой, подобной этой?

namespace boost {

struct none_t {};

none_t const none;

} // namespace boost

1 ответ

Решение

Ах, я никогда не думал копать глубже.

Одно (более или менее очевидное) преимущество перед обычным structэто сейчас none оценивает false в булевых контекстах.

Одно преимущество перед "оценивается как ложное" состоит в том, что указатель на член предотвращается от вредоносного продвижения до целочисленных типов.

Итак, я думаю, что он предлагает безопасный и краткий способ иметь объект, который оценивает false,

РЕДАКТИРОВАТЬ: Нужно признать здесь (гул...) структура идиома Safe Bool.

Другие вопросы по тегам