C++20中引入了 <ranges>
库,可方便灵活地对容器中的元素进行查找等操作。不过对于有些环境,比如当前的Android平台,尽管Clang编译器能支持较完整的C++20特性,但无奈其C++标准库中缺少了 <ranges>
的实现,因此我们对于某些使用该库的代码需要做一些替代实现。
以下示例代码演示了 <ranges>
库中一些常规操作的替代实现方案:
#include <cstdio>
#include <functional>
#include <algorithm>
#include <ranges>
extern "C" void CPPTest()
{
struct S
{
int a, b;
bool IsValid() const
{
return a >= 0 && b >= 0;
}
};
std::vector<S> v = { {1, 8}, {0, 0}, { 2, 1 }, {2, 1}, {3, 2}, {4, 4}, {5, 2} };
auto const it1 = std::ranges::find(v, 2, &S::b);
auto const it2 = std::find_if(v.begin(), v.end(), [](const S& s) -> bool {
return s.b == 2;
});
if (it1 == it2) {
puts("Equal!");
}
auto const it3 = std::ranges::lower_bound(v, 2, {}, &S::a);
auto const it4 = std::lower_bound(v.begin(), v.end(), 2, [](const S& s1, const int& val) -> bool {
return s1.a < val;
});
if (it3 == it4) {
puts("Equal!");
}
auto const equal = [](const S& s1, const S& s2) -> bool {
return s1.a != s2.a || s1.b != s2.b;
};
auto const resolver = [](const S &value) {
return value;
};
auto const it5 = std::ranges::adjacent_find(v, std::not_fn(equal), resolver);
auto const it6 = std::adjacent_find(v.begin(), v.end(), [&equal, &resolver](const S& s1, const S& s2) -> bool {
return std::not_fn(equal)(resolver(s1), resolver(s2));
});
if (it5 == it6) {
puts("Equal!");
}
auto const it7 = std::ranges::upper_bound(v, 4, {}, &S::a);
auto const it8 = std::upper_bound(v.begin(), v.end(), 4, [](const int& val, const S& s1) -> bool {
return val < s1.a;
});
if (it7 == it8) {
puts("Equal!");
}
auto const b1 = std::ranges::all_of(v, &S::IsValid);
auto const b2 = std::all_of(v.begin(), v.end(), [](const S& s) -> bool {
return s.IsValid();
});
if (b1 == b2) {
puts("Equal!");
}
}
以上代码示例演示了如何通过已有的标准库实现来替代新增的 <ranges>
库中的功能。当然,有些替换实现也能直接用Boost库做等价替换,各位可以根据自己的喜好做选取。