如何获取C++20 std::ranges range的值类型及优雅实现make_vector函数
在C++20中确定std::ranges::range的值类型并实现优雅的make_vector函数
C++20的Ranges库已经提供了标准的类型萃取工具,能直接获取range的元素值类型,无需手动通过迭代器推导。
1. 标准类型萃取工具
要获取std::ranges::range的值类型,直接使用std::ranges::range_value_t<Range>即可。它等价于std::iter_value_t<std::ranges::iterator_t<Range>>,对应range迭代器指向的底层值类型,完全适配std::vector的存储需求。
相关的补充类型萃取:
std::ranges::range_reference_t<Range>:迭代器解引用后的类型(通常为引用类型)std::ranges::range_common_reference_t<Range>:元素的通用引用类型
2. 清晰明确的函数声明
你想要的明确函数声明可以直接通过标准萃取实现:
#include <ranges> #include <vector> template<std::ranges::range Range> std::vector<std::ranges::range_value_t<Range>> make_vector(const Range& range);
3. 简洁优雅的实现
基于标准萃取,实现可以大幅简化,无需手动推导迭代器和解引用类型:
基础遍历版本
template<std::ranges::range Range> std::vector<std::ranges::range_value_t<Range>> make_vector(const Range& range) { using ValueType = std::ranges::range_value_t<Range>; std::vector<ValueType> retval; for (const auto& elem : range) { retval.push_back(elem); } return retval; }
标准算法简化版本
用std::ranges::copy替代手动遍历,代码更紧凑:
template<std::ranges::range Range> std::vector<std::ranges::range_value_t<Range>> make_vector(const Range& range) { using ValueType = std::ranges::range_value_t<Range>; std::vector<ValueType> retval; std::ranges::copy(range, std::back_inserter(retval)); return retval; }
4. 扩展:支持右值range(可选)
如果需要处理右值range以避免元素拷贝(比如临时生成的range),可以改用转发引用配合std::ranges::move提升效率:
template<std::ranges::range Range> std::vector<std::ranges::range_value_t<std::remove_cvref_t<Range>>> make_vector(Range&& range) { using ValueType = std::ranges::range_value_t<std::remove_cvref_t<Range>>; std::vector<ValueType> retval; std::ranges::move(std::forward<Range>(range), std::back_inserter(retval)); return retval; }
内容的提问来源于stack exchange,提问作者levzettelin
相关产品推荐
相关产品推荐

