转发容器的价值类别?

问题描述 投票:0回答:0

在 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&&
,这将不起作用。

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&&
最终成为
std::span<S>&&
,我不希望跨度的右值适用于
S
!我认为(?)我们想要考虑
std::ranges::enable_view<Range>
,如果是这样,请忽略
Range&&
的值类别,而只使用解引用迭代器中的值类别。

此外,我们希望它适用于

std::move_iterator
的范围和发电机。

是否有任何标准的 C++ 功能?

我发现了类似的问题,但它们不是最新的或者没有完全理解我的观点。例如,矢量的通用参考

c++ perfect-forwarding
© www.soinside.com 2019 - 2024. All rights reserved.