在 C++20 中,我想编写通用代码来获取容器或视图并完美地转发每个元素。也就是说,如果我有这样令人讨厌的类型:
struct S {
struct tag {}; // So we have a way to construct an S.
S(tag) {}
S() = delete; // S isn't semiregular.
S(const S&) = delete;
S(S&&) = default; // It's movable
S& operator=(const S&) = delete;
S& operator=(S&&) = default;
};
我希望能够将
std::vector<S>
传递给一个函数并让它消耗 S
es.
我原本以为这会起作用:
template <typename Range, typename Fn>
void myForEach(Range&& range, Fn f) {
for (auto&& x : std::forward<Range>(range)) {
f(std::forward<decltype(x)>(x));
}
}
但即使
FWD(range)
是一个右值,x
不是,所以如果 f
需要一个 S&&
,这将不起作用。
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&&
最终成为 std::span<S>&&
,我不希望跨度的右值适用于 S
!我认为(?)我们想要考虑std::ranges::enable_view<Range>
,如果是这样,请忽略Range&&
的值类别,而只使用解引用迭代器中的值类别。
此外,我们希望它适用于
std::move_iterator
的范围和发电机。
是否有任何标准的 C++ 功能?
我发现了类似的问题,但它们不是最新的或者没有完全理解我的观点。例如,矢量的通用参考