如何在 C++17 中应用链接关联性

How to apply chaining-associativity in C++17

本文关键字:应用 链接 关联性 C++17      更新时间:2023-10-16
#include <numeric>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
vector<int> v1{1,2,3};
vector<int> v2{3,2,1};
vector<int> v3{3,2,1,2};
int increasing = reduce(v1.begin(), v1.end(), 1, less<int>());
for_each(v1.begin(), v1.end(),[](int &k){cout<< k <<",";});
cout << " Increasing? " << increasing << endl;
increasing = reduce(v2.begin(), v2.end(), 1, less<int>());
for_each(v2.begin(), v2.end(),[](int &k){cout<< k <<",";});
cout << " Increasing? " << increasing << endl;
increasing = reduce(v3.begin(), v3.end(), 1, less<int>());
for_each(v3.begin(), v3.end(),[](int &k){cout<< k <<",";});
cout << " Increasing? " << increasing << endl;
}

在这个例子中,我测试了向量是否所有元素都在增加,结果如下:

1,2,3, Increasing? 1
3,2,1, Increasing? 0
3,2,1,2, Increasing? 0

向量v1并且v2正确通过测试,但v3没有,因为默认情况下less<int>函数作为左关联应用,即它仅应用于左侧的元素。

为了正确测试v3,应将less<int>函数应用于整个向量和AFAIK,这是通过所谓的链结合性实现的。

请注意,我不只是在尝试检查排序序列。我正在寻找一种为任何函数实现这种所谓的链接关联性的方法,为了示例,这里是less<int>

因此,我想以简洁的方式将less<int>应用为链接关联,即不会弄乱代码。我该怎么做?

谢谢。

我意识到我的第一个建议是使用std::is_sorted()在两个具有相同值的相邻元素的情况下不起作用 - 它们已排序,但不会增加。但是,如果您想使用标准算法而不是使用手写循环,std::adjacent_find()有效:

#include <algorithm>
#include <iostream>
#include <vector>
// Version using an explicit binary predicate
template <class It, class F>
bool increasing(const It beg, const It end, F op) {
return std::adjacent_find(beg, end, [&op](const auto &a, const auto &b) {
return !op(a, b);
}) == end;
}
// Version using <
template <class It> bool increasing(const It beg, const It end) {
return std::adjacent_find(beg, end, [](const auto &a, const auto &b) {
return !(a < b);
}) == end;
}
int main() {
std::vector<int> v1{1, 2, 3}, v2{3, 2, 1}, v3{3, 2, 1, 2};
std::cout << std::boolalpha;
std::cout << "v1 increasing: " << increasing(v1.begin(), v1.end()) << 'n';
std::cout << "v2 increasing: "
<< increasing(v2.begin(), v2.end(), std::less<int>()) << 'n';
std::cout << "v3 increasing: " << increasing(v3.begin(), v3.end()) << 'n';
return 0;
}

v1 increasing: true
v2 increasing: false
v3 increasing: false