关于libstdc++中std::expected部分方法省略return后的else、部分不省略的原因问询
关于libstdc++中std::expected的error_or省略return后else,而and_then不省略的原因
嗨,我最近在研究master分支里libstdc++对std::expected的实现,发现了一个有意思的细节:error_or和and_then两个成员函数,对return后的else处理方式不一样,先看对应的代码片段:
// error_or 实现片段 template<typename _Gr = _Er> constexpr _Er error_or(_Gr&& __e) && { static_assert( is_move_constructible_v<_Er> ); static_assert( is_convertible_v<_Gr, _Er> ); if (_M_has_value) return std::forward<_Gr>(__e); // 此处省略了else return std::move(_M_unex); } // and_then 实现片段 template<typename _Fn> requires is_constructible_v<_Er, _Er&> constexpr auto and_then(_Fn&& __f) & { using _Up = __expected::__result<_Fn, _Tp&>; static_assert(__expected::__is_expected<_Up>, "the function passed to std::expected<T, E>::and_then " "must return a std::expected"); static_assert(is_same_v<typename _Up::error_type, _Er>, "the function passed to std::expected<T, E>::and_then " "must return a std::expected with the same error_type"); if (has_value()) return std::__invoke(std::forward<_Fn>(__f), _M_val); else // 此处未省略else return _Up(unexpect, _M_unex); }
可以看到,error_or里在return之后直接省略了else,但and_then里却保留了else。我翻了GNU编码标准和GCC编码规范,没找到相关强制规则,那这到底是风格不一致,还是有其他深层原因?
最核心的原因:风格层面的小差异
首先可以确定,这大概率是代码维护过程中的风格小不一致。libstdc++由多名开发者共同维护,不同开发者的写法偏好可能存在差异;就算是同一个开发者,在不同场景下也可能根据代码的可读性选择不同的写法——GNU的编码规范并没有强制要求return后必须加或省略else,更多是基于可读性的灵活选择。
可读性导向的细微考量(非技术强制)
如果硬要找超出“纯风格”的细节原因,可能和代码的可读性设计有关:
- 在
error_or中,两个return的逻辑非常直白:有值就返回传入的参数,否则返回内部的错误值。第一个return的表达式很短,省略else不会让逻辑模糊,反而让代码更紧凑清爽。 - 在
and_then中,两个return的语句复杂度更高:成功分支是调用传入的函数生成结果,失败分支是用unexpect构造一个新的expected对象。保留else可以更明确地把“失败分支的返回”和前面的“成功分支”做逻辑对立绑定,避免读者因为代码长度问题,产生分支对应关系的误解。
不过这本质上还是可读性导向的风格选择,没有技术上的强制要求——编译器对两种写法的处理完全一致,return之后的代码本来就不会执行,加不加else都不会影响编译结果、性能或语义。
总结
没有超出代码风格之外的深层技术原因,最合理的解释就是不同场景下的开发者为了可读性选择了不同的写法,属于代码维护中的小风格差异。
内容来源于stack exchange
相关产品推荐
相关产品推荐

