std::optional是17标准中增加的管理可选值的类模板,以往经验中如果某个函数的返回值可能失败,如何判断这个失败值和传递这个失败值都需要些额外的手段,optional的出现则很好的解决了这个问题。以下是gcc13版本中std::optional源码的个人解析:
std::optional实现内各类型关系 
optional 
首先是optional模板声明及内部别名:
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 template <typename  _Tp>  class  optional    : private  _Optional_base<_Tp>,     private  _Enable_copy_move<      is_copy_constructible_v<_Tp>,      __and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,      is_move_constructible_v<_Tp>,      __and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,      optional<_Tp>>   {     static_assert (!is_same_v<remove_cv_t <_Tp>, nullopt_t >);     static_assert (!is_same_v<remove_cv_t <_Tp>, in_place_t >);     static_assert (is_object_v<_Tp> && !is_array_v<_Tp>);   private :     using  _Base = _Optional_base<_Tp>;          template <typename  _Up>   using  __not_self = __not_<is_same<optional, __remove_cvref_t <_Up>>>;     template <typename  _Up>   using  __not_tag = __not_<is_same<in_place_t , __remove_cvref_t <_Up>>>;     template <typename ... _Cond>   using  _Requires = enable_if_t <__and_v<_Cond...>, bool >; 
 
_Enable_copy_move为gcc内部的一个helper模板,四个模板参数对应于是否有复制构造、复制赋值、移动构造、移动赋值,其定义和其中一个特化长这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 template <bool  _Copy, bool  _CopyAssignment,         bool  _Move, bool  _MoveAssignment,          typename  _Tag = void >   struct  _Enable_copy_move { };      template <typename  _Tag>   struct  _Enable_copy_move <false , true , true , true , _Tag>   {     constexpr  _Enable_copy_move() noexcept                           = default ;     constexpr  _Enable_copy_move(_Enable_copy_move const &) noexcept   = delete ;     constexpr  _Enable_copy_move(_Enable_copy_move&&) noexcept        = default ;     _Enable_copy_move&     operator =(_Enable_copy_move const &) noexcept                     = default ;     _Enable_copy_move&     operator =(_Enable_copy_move&&) noexcept                          = default ;   }; 
 
由于子类optional<T>内没有没有数据成员固没有声明任何五个特殊成员函数,所以在这里的含义即是如果optional<T>的T不拥有复制构造则optional<T>因该helper父类没有复制构造亦不拥有复制构造,其他三个特殊成员函数同理。
_Optional_base 
optional<T>子类没有数据成员,成员方法皆为父类方法的封装,所以实现还要看这个_Optional_base:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 template <typename  _Tp,     bool  = is_trivially_copy_constructible_v<_Tp>,      bool  = is_trivially_move_constructible_v<_Tp>>   struct  _Optional_base   : _Optional_base_impl<_Tp, _Optional_base<_Tp>>   {          constexpr  _Optional_base() = default ;          template <typename ... _Args,          enable_if_t <is_constructible_v<_Tp, _Args...>, bool > = false >   constexpr  explicit    _Optional_base(in_place_t , _Args&&... __args)   : _M_payload(in_place, std::forward<_Args>(__args)...)   { }     template <typename  _Up, typename ... _Args,          enable_if_t <is_constructible_v<_Tp,                         initializer_list<_Up>&,                         _Args...>, bool > = false >   constexpr  explicit    _Optional_base(in_place_t ,              initializer_list<_Up> __il,              _Args&&... __args)   : _M_payload(in_place, __il, std::forward<_Args>(__args)...)   { }          constexpr      _Optional_base(const  _Optional_base& __other)     : _M_payload(__other._M_payload._M_engaged, __other._M_payload)     { }     constexpr      _Optional_base(_Optional_base&& __other)     noexcept (is_nothrow_move_constructible_v<_Tp>)     : _M_payload(__other._M_payload._M_engaged,          std::move (__other._M_payload))     { }          _Optional_base& operator =(const  _Optional_base&) = default ;     _Optional_base& operator =(_Optional_base&&) = default ;     _Optional_payload<_Tp> _M_payload;   }; 
 
_Optional_base内包含实际存储对象的_Optional_payload<_Tp> _M_payload,这里为了让这个类型拥有和_Tp同样的“可平凡复制构造性”、“可平凡移动构造性”,特化了其他三个版本(_Optional_base<_Tp, false, true>,_Optional_base<_Tp, true, false>,_Optional_base<_Tp, true, true>)声明该类的复制构造、移动构造,比如_Optional_base<_Tp, false, true>:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 template <typename  _Tp>  struct  _Optional_base <_Tp, false , true >   : _Optional_base_impl<_Tp, _Optional_base<_Tp>>   {          constexpr  _Optional_base() = default ;          template <typename ... _Args,          enable_if_t <is_constructible_v<_Tp, _Args...>, bool > = false >   constexpr  explicit    _Optional_base(in_place_t , _Args&&... __args)   : _M_payload(in_place, std::forward<_Args>(__args)...)   { }     template <typename  _Up, typename ... _Args,          enable_if_t <is_constructible_v<_Tp,                         initializer_list<_Up>&,                         _Args...>, bool > = false >   constexpr  explicit    _Optional_base(in_place_t ,              initializer_list<_Up> __il,              _Args... __args)   : _M_payload(in_place, __il, std::forward<_Args>(__args)...)   { }          constexpr  _Optional_base(const  _Optional_base& __other)     : _M_payload(__other._M_payload._M_engaged, __other._M_payload)     { }     constexpr  _Optional_base(_Optional_base&& __other) = default ;          _Optional_base& operator =(const  _Optional_base&) = default ;     _Optional_base& operator =(_Optional_base&&) = default ;     _Optional_payload<_Tp> _M_payload;   }; 
 
可以看到和开始的模板类相比仅是复制构造被声明为了=default,开始的模板类其实也就是_Optional_base<_Tp, false, false>。这里为了不写很多相同的代码,把涉及_M_payload的很多封装操作封装进了_Optional_base_impl,而_M_payload也通过模板参数_Optional_base_impl<_Tp, _Optional_base<_Tp>>从子类传递给了父类。
_Optional_base_impl 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 template <typename  _Tp, typename  _Dp>  class  _Optional_base_impl    {   protected :     using  _Stored_type = remove_const_t <_Tp>;               template <typename ... _Args>   constexpr  void    _M_construct(_Args&&... __args)   noexcept (is_nothrow_constructible_v<_Stored_type, _Args...>)   {     static_cast <_Dp*>(this )->_M_payload._M_construct(       std::forward<_Args>(__args)...);   }     constexpr  void      _M_destruct() noexcept      { static_cast <_Dp*>(this )->_M_payload._M_destroy(); }          constexpr  void      _M_reset() noexcept      { static_cast <_Dp*>(this )->_M_payload._M_reset(); }     constexpr  bool  _M_is_engaged() const  noexcept      { return  static_cast <const  _Dp*>(this )->_M_payload._M_engaged; }          constexpr  _Tp&     _M_get() noexcept      {   __glibcxx_assert(this ->_M_is_engaged());   return  static_cast <_Dp*>(this )->_M_payload._M_get();     }     constexpr  const  _Tp&     _M_get() const  noexcept      {   __glibcxx_assert(this ->_M_is_engaged());   return  static_cast <const  _Dp*>(this )->_M_payload._M_get();     }   }; 
 
从代码开始的注释中也印证我的推断,_Optional_base_impl的存在只是为了减少各特化版本中的重复代码。作为父类的_Optional_base_impl通过static_cast<_Dp*>(this)->_M_payload来调用子类内的_M_payload。
_Optional_payload 
实际存储值的_Optional_payload声明:
1 2 3 4 5 6 7 8 9 10 11 template  <typename  _Tp,      bool   =         is_trivially_destructible_v<_Tp>,       bool   =         is_trivially_copy_assignable_v<_Tp>         && is_trivially_copy_constructible_v<_Tp>,       bool   =         is_trivially_move_assignable_v<_Tp>         && is_trivially_move_constructible_v<_Tp>>   struct  _Optional_payload; 
 
又是可平凡析构、可平凡复制、可平凡移动的模板参数,这个实际值管理的子类同样视实际值的平凡性对应不同的_Optional_payload:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 template  <typename  _Tp>  struct  _Optional_payload <_Tp, true , true , true >   : _Optional_payload_base<_Tp>   {     using  _Optional_payload_base<_Tp>::_Optional_payload_base;     _Optional_payload() = default ;   }; template  <typename  _Tp>  struct  _Optional_payload <_Tp, true , false , true >   : _Optional_payload_base<_Tp>   {     using  _Optional_payload_base<_Tp>::_Optional_payload_base;     _Optional_payload() = default ;     ~_Optional_payload() = default ;     _Optional_payload(const  _Optional_payload&) = default ;     _Optional_payload(_Optional_payload&&) = default ;     _Optional_payload& operator =(_Optional_payload&&) = default ;          constexpr      _Optional_payload&     operator =(const  _Optional_payload& __other)     {   this ->_M_copy_assign(__other);   return  *this ;     }   }; template  <typename  _Tp>  struct  _Optional_payload <_Tp, true , true , false >   : _Optional_payload_base<_Tp>   {     using  _Optional_payload_base<_Tp>::_Optional_payload_base;     _Optional_payload() = default ;     ~_Optional_payload() = default ;     _Optional_payload(const  _Optional_payload&) = default ;     _Optional_payload(_Optional_payload&&) = default ;     _Optional_payload& operator =(const  _Optional_payload&) = default ;          constexpr      _Optional_payload&     operator =(_Optional_payload&& __other)     noexcept (__and_v<is_nothrow_move_constructible<_Tp>,              is_nothrow_move_assignable<_Tp>>)     {   this ->_M_move_assign(std::move (__other));   return  *this ;     }   }; 
 
可以看出区别在于非平凡复制、非平凡移动时有特殊的复制赋值、移动赋值,先不管这里为什么这么写,看看这个基类_Optional_payload_base:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 template  <typename  _Tp>  struct  _Optional_payload_base    {     using  _Stored_type = remove_const_t <_Tp>;     _Optional_payload_base() = default ;     ~_Optional_payload_base() = default ;               struct  _Empty_byte  { };     template <typename  _Up, bool  = is_trivially_destructible_v<_Up>>   union  _Storage   {        _Empty_byte _M_empty;     _Up _M_value;   };        _Storage<_Stored_type> _M_payload;     bool  _M_engaged = false ;   }; 
 
_Storage<_Stored_type> _M_payload即为实际存储的值,template _Storage为了保证可平凡析构的一致性同样写了个没有声明析构的可平凡析构版本的模板,和特化了一个带有空析构函数的版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38       template <typename  _Up, bool  = is_trivially_destructible_v<_Up>>     union  _Storage     {       constexpr  _Storage() noexcept  : _M_empty() { }       template <typename ... _Args>         constexpr          _Storage(in_place_t , _Args&&... __args)         : _M_value(std::forward<_Args>(__args)...)         { }       template <typename  _Vp, typename ... _Args>         constexpr          _Storage(std::initializer_list<_Vp> __il, _Args&&... __args)         : _M_value(__il, std::forward<_Args>(__args)...)         { } #if  __cplusplus >= 202002L       template <typename  _Fn, typename  _Arg>         constexpr          _Storage(_Optional_func<_Fn> __f, _Arg&& __arg)         : _M_value(std::__invoke(std::forward<_Fn>(__f._M_f),                      std::forward<_Arg>(__arg)))         { } #endif        _Empty_byte _M_empty;       _Up _M_value;     };            template <typename  _Up>     union  _Storage <_Up, false >     {                     _GLIBCXX20_CONSTEXPR ~_Storage() { }     };     
 
从上面这部分代码可以看出optional实际存储在该union中。_Optional_payload_base中的_M_engaged表示实际是否存储值,由于字节对齐,一个optional<T>的大小可能将占用更大的内存。 
以optional<int32_t>对象为例,其结构为这样: 
std::optional成员函数实现 
构造函数 
以template < class U = T >constexpr optional( U&& value );为例,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 template <typename  _Up = _Tp,     _Requires<__not_self<_Up>, __not_tag<_Up>,        is_constructible<_Tp, _Up>,        is_convertible<_Up, _Tp>> = true > constexpr optional (_Up&& __t )noexcept (is_nothrow_constructible_v<_Tp, _Up>): _Base(std::in_place, std::forward<_Up>(__t )) { } template <typename  _Up = _Tp,     _Requires<__not_self<_Up>, __not_tag<_Up>,        is_constructible<_Tp, _Up>,        __not_<is_convertible<_Up, _Tp>>> = false > explicit  constexpr optional (_Up&& __t )noexcept (is_nothrow_constructible_v<_Tp, _Up>): _Base(std::in_place, std::forward<_Up>(__t )) { } 
 
_Base即是_Optional_base<_Tp>,通过in_place标签构造:
1 2 3 4 5 6 7 template <typename ... _Args,     enable_if_t <is_constructible_v<_Tp, _Args...>, bool > = false > constexpr  explicit _Optional_base(in_place_t , _Args&&... __args) : _M_payload(in_place, std::forward<_Args>(__args)...) { } 
 
构造_M_payload,_Optional_payload使用基类_Optional_payload_base的构造:
1 2 3 4 5 6 template <typename ... _Args>constexpr _Optional_payload_base(in_place_t  __tag, _Args&&... __args) : _M_payload(__tag, std::forward<_Args>(__args)...),   _M_engaged(true ) { } 
 
至最终_Storage构造:
1 2 3 4 5 template <typename ... _Args>  constexpr    _Storage(in_place_t , _Args&&... __args)   : _M_value(std::forward<_Args>(__args)...)   { } 
 
以上即为optional其中一个构造的全过程。
reset 
从上述构造函数的过程可以看出实际操作都是在payload类型里,这里也就不多描述外层接口,_Optional_payload_base的_M_reset过程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 constexpr  void _M_destroy() noexcept  {   _M_engaged = false ;   _M_payload._M_value.~_Stored_type(); } constexpr  void _M_reset() noexcept  {   if  (this ->_M_engaged)     _M_destroy(); } 
 
emplace 
1 2 3 4 5 6 7 8 9 10 11   template <typename ... _Args>   _GLIBCXX20_CONSTEXPR   enable_if_t <is_constructible_v<_Tp, _Args...>, _Tp&>   emplace (_Args&&... __args)   noexcept (is_nothrow_constructible_v<_Tp, _Args...>)   {     this ->_M_reset();     this ->_M_construct(std::forward<_Args>(__args)...);     return  this ->_M_get();   } 
 
省略中间代码,_Optional_payload_base中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 template <typename ... _Args> constexpr  void _M_construct(_Args&&... __args) noexcept (is_nothrow_constructible_v<_Stored_type, _Args...>){   std::_Construct(std::__addressof(this ->_M_payload._M_value),           std::forward<_Args>(__args)...);   this ->_M_engaged = true ; }      constexpr  _Tp&_M_get() noexcept  { return  this ->_M_payload._M_value; } 
 
_M_construct在_M_payload._M_value上原地构造对象后置_M_engaged为true。
swap 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 _GLIBCXX20_CONSTEXPR void  swap (optional& __other) noexcept (is_nothrow_move_constructible_v<_Tp>      && is_nothrow_swappable_v<_Tp>)  {  using  std::swap;   if  (this ->_M_is_engaged() && __other._M_is_engaged())     swap (this ->_M_get(), __other._M_get());   else  if  (this ->_M_is_engaged())   {     __other._M_construct(std::move (this ->_M_get()));     this ->_M_destruct();   }   else  if  (__other._M_is_engaged())   {     this ->_M_construct(std::move (__other._M_get()));     __other._M_destruct();   } } 
 
逻辑也比较简单不赘述,这里再贴下_M_destruct实现:
1 2 3 4 constexpr  void _M_destruct() noexcept  { static_cast <_Dp*>(this )->_M_payload._M_destroy(); } 
 
1 2 3 4 5 6 7   constexpr  void    _M_destroy() noexcept    {     _M_engaged = false ;     _M_payload._M_value.~_Stored_type();   }