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 可以满足我的需求吗?
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.