Каково обоснование реализации 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.