C++如何用concepts匹配容器const性实现返回值类型自动推导
解决方案
C++20 标准库的 ranges 组件已经提供了现成的工具,完全可以满足你的需求,无需自己手写复杂的类型萃取和冗余的match_const实现。
你需要的随容器const性自动调整的引用类型,对应的标准库别名是std::ranges::range_reference_t,它会自动识别传入容器的const属性,返回对应带/不带const的引用类型;同时标准库也内置了std::ranges::range概念,已经覆盖了你自定义的Container概念对begin/end/size的要求,可以直接使用。
最简实现
#include <ranges> #include <algorithm> #include <boost/optional.hpp> template <std::ranges::range Container> auto ofind(Container& container, const auto& value) -> boost::optional<std::ranges::range_reference_t<Container>> { if (auto it = std::ranges::find(container, value); it != container.end()) { return *it; } return boost::none; }
这个写法已经非常接近你理想中的形式,std::ranges::range_reference_t<Container>就等价于你提到的Container::real_reference。
效果验证
用你给出的测试场景验证,类型匹配完全符合预期:
#include <vector> #include <type_traits> const std::vector<int> cvi{1,2,3}; std::vector<int> vi{1,2,3}; // 常量容器返回 const int& 包装的optional static_assert(std::is_same_v<boost::optional<const int&>, decltype(ofind(cvi, 1))>); // 非常量容器返回 int& 包装的optional static_assert(std::is_same_v<boost::optional<int&>, decltype(ofind(vi, 1))>);
补充说明
如果你坚持要自定义Container概念,也可以搭配自己的关联类型别名实现,不过对于绝大多数场景,标准库的range相关工具已经足够用,无需重复造轮子。
内容的提问来源于stack exchange,提问作者NoSenseEtAl
相关产品推荐
相关产品推荐

