c++20范围是否有任何不返回值的视图函数?

Tro*_*yvs 4 c++ c++20 std-ranges

我可以使用 std::views::transform 创建新stream-style容器,然后打印它,如下所示:

#include<iostream>
#include<vector>
#include<ranges>
using namespace std;
int main() {
    // clang -std=c++20
    std::vector<int> input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    auto output = input 
        | std::views::filter([](const int n) {return n % 3 == 0; })
        | std::views::transform([](const int n) {return n * n; });
    for (auto o : output) {
        cout << o << endl;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

是的,它有效,但我希望简单地for将我的循环写入由 连接的管道中|,有没有办法将代码更改为:

input 
        | std::views::filter([](const int n) {return n % 3 == 0; })
        | std::views::transform([](const int n) {return n * n; })
        | std::views::SOME_FUNCTION(cout<<n<<endl);
Run Code Online (Sandbox Code Playgroud)

这避免了我的for循环。

所以我的问题是:std::views有 SOME_FUNCTION 可以满足我的需求吗?

Fur*_*ish 8

C++20(或 C++23)中没有这样的适配器。我还发现缺少此功能,因为它将使程序员能够转向更一致和更“纯粹”的函数式风格,而不是通过管道()编写表达式|,然后在循环中使用它。

最终,我希望std::views::for_each(或者也许std::actions::for_each,如果actions达到标准的话)能够做到这一点。截至目前,您可以实现自己的for_each可管道化,但不幸的是,这不会像人们希望的那样标准,在 C++23 中会成为非标准,因为在 C++23 中定义的正确方法rande-adaptors 将使用range_adaptor_closure<T>. 此外,根据P2387R3

如果重载决策选择程序定义的函数,则涉及cv D类型的对象作为运算符的操作数的表达式的行为是未定义的。|operator|

直接来源

因此,在 C++23 中,您可以自由地轻松地创建自己的,terminal::for_each这将以完全符合标准的方式消耗函数式风格的范围。

不过,目前最安全的做法是坚持使用基于范围的for循环或std::ranges::for_each.