是否存在类似std::forward的std::ranges完美转发移动/拷贝工具?
合并moveOrCopy函数的方案及相关range工具问题
如何将以下两个moveOrCopy函数合并为一个?是否存在类似std::forward、针对std::ranges的工具?
原代码如下:
#include <ranges> #include <vector> #include <algorithm> template<class RangeIn, class RangeOut> void moveOrCopy(RangeIn& from, RangeOut& to) { std::ranges::copy(from, std::back_inserter(to)); } template<class RangeIn, class RangeOut> requires std::is_rvalue_reference_v<RangeIn&&> void moveOrCopy(RangeIn&& from, RangeOut& to) { std::ranges::move(from, std::back_inserter(to)); } void test() { std::vector<int> a, b; moveOrCopy(a, b); // 拷贝 moveOrCopy(std::move(a), b); // 移动 }
注:std::ranges::forward_range仅用于描述具备前向迭代器的range概念,和完美转发无关。
合并函数的实现方案
可以通过万能引用配合编译期值类别判断,将两个函数合并为一个模板函数:
#include <ranges> #include <vector> #include <algorithm> #include <type_traits> template<class RangeIn, class RangeOut> void moveOrCopy(RangeIn&& from, RangeOut& to) { if constexpr (std::is_rvalue_reference_v<RangeIn&&>) { std::ranges::move(std::forward<RangeIn>(from), std::back_inserter(to)); } else { std::ranges::copy(std::forward<RangeIn>(from), std::back_inserter(to)); } } void test() { std::vector<int> a, b; moveOrCopy(a, b); // 拷贝 moveOrCopy(std::move(a), b); // 移动 }
实现逻辑:
- 用
RangeIn&&万能引用接收传入的range,保留其值类别信息 - 通过
std::is_rvalue_reference_v<RangeIn&&>在编译期判断传入的是右值还是左值 - 用
std::forward<RangeIn>(from)完美转发原range,确保算法能正确利用其值类别 - 根据判断结果选择调用
std::ranges::move(右值时)或std::ranges::copy(左值时)
如果使用C++23,还可以用std::forward_like简化值类别转发逻辑:
template<class RangeIn, class RangeOut> void moveOrCopy(RangeIn&& from, RangeOut& to) { auto&& elements = std::forward_like<RangeIn>(from); if constexpr (std::is_rvalue_reference_v<decltype(elements)>) { std::ranges::move(elements, std::back_inserter(to)); } else { std::ranges::copy(elements, std::back_inserter(to)); } }
关于range专属的完美转发工具
目前C++标准库中没有专门针对std::ranges的类似std::forward的工具,但通过万能引用+std::forward/std::forward_like,完全可以实现对range的完美转发需求。
内容的提问来源于stack exchange,提问作者jozxyqk
相关产品推荐
相关产品推荐

