使用 g++-std=C++20或更高版本,可以编译以下内容(假设 vec 是适当类型的向量):
auto isEven = [](auto i) { return i % 2 == 0; }
auto filtered = vec | std::views::filter(isEven);
auto minEven = std::ranges::min_element(filtered);
Run Code Online (Sandbox Code Playgroud)
但以下情况则不然( 的参数数量错误std::ranges::__min_element_fn):
auto isEven = [](auto i) { return i % 2 == 0; }
auto minEven = vec | std::views::filter(isEven) | std::ranges::min_element();
Run Code Online (Sandbox Code Playgroud)
这里的理由是什么?我如何知道哪些与系列相关的漂亮设施可以合并到管道中?(后者是我凭直觉写的;从概念上讲,这似乎是执行此操作的“新范围方式”。)
在 C++20 中,事情很简单。所有视图都可以通过管道传输。没有算法可以通过管道传输。如果它位于views命名空间中,则可以对其进行管道传输,并且任何视图都可以针对范围进行管道传输。也就是说,如果 的至少一个操作数|来自views命名空间,并且另一个操作数是一个范围,那么它可以通过管道传输。否则不能。
另一种记住方式是管道创建范围。min_element不创建范围;它只是找到一个范围的特定元素。它的结果不是一个范围,所以它不是可以通过管道传输的东西。
后来的版本决定根据当时最有利的方式来管道或不管道。没有任何规律或理由,只是提出并接受的建议。ranges::to之所以能够被管道化,是因为它的作者提出了管道化,并且委员会接受了它。该提案的任何版本都没有尝试合理解释为什么可管道对象位于ranges命名空间中。这就是它的提议。
试图在什么可以通过管道传输和什么不能通过管道传输方面保持一致显然不是委员会的目标。也许将来通用的范围算法将是可管道化的。也许不会。