如何在C++中完美转发容器或视图的元素值类别?
C++20泛型遍历的完美转发实现问题
我想在C++20中编写泛型代码,接收容器或视图并完美转发每个元素。比如针对下面这个特殊类型S:
struct S { struct tag {}; // 用于构造S的标签 S(tag) {} S() = delete; // S不满足半正则要求 S(const S&) = delete; S(S&&) = default; // 可移动 S& operator=(const S&) = delete; S& operator=(S&&) = default; };
我希望能把std::vector<S>传入函数并消费其中的S对象。
我原本以为下面这段代码可行:
template <typename Range, typename Fn> void myForEach(Range&& range, Fn f) { for (auto&& x : std::forward<Range>(range)) { f(std::forward<decltype(x)>(x)); } }
但问题在于,即便std::forward<Range>(range)是右值,x也不会是右值,所以如果f需要S&&的话,这段代码无法正常工作。
C++23新增的std::forward_like看起来是个可行方案:
template <typename Range, typename Fn> void myForEach(Range&& range, Fn f) { for (auto&& x : range) { f(std::forward_like<Range>(x)); } }
它会转发range的值类别,但如果range是视图呢?比如当Range&&是std::span<S>&&时,我不希望把span的右值属性传递给S!我觉得需要判断std::ranges::enable_view<Range>,如果是视图的话,就忽略Range&&的值类别,只使用迭代器解引用的原始值类别。
另外,我还希望这个方案能支持std::move_iterator和生成器(generators)对应的范围。
请问标准C++中有没有现成的功能可以实现这一点?
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

