可以使用std::sort 对向量进行排序,使用std::equal_range 可以找到具有指定权重的元素范围。
但是,正如丹尼尔在评论中指出的那样,getASpecificWeight() 很可能返回一个双精度而不是 Structure,因此为了调用 equal_range,我们需要创建一个虚拟 Structure 或将doubles 与Structures 与所需语义进行比较的函数对象。单个 lambda 不起作用,因为二进制搜索需要能够比较 Structures 和两种方式的权重。
备选方案 1:使用虚拟结构
首先,让我们创建一个虚拟Structure,因为它的代码更少。
总的来说,它可能看起来像这样
auto sort_structure_by_weight_asc = [](Structure const& s1, Structure const& s2) {
return s1.weight < s2.weight;
};
std::sort(structures.begin(), structures.end(),
sort_structure_by_weight_asc);
for (auto i = 0; i < 1000; ++i) {
auto weight = GetASpecificWeight();
auto const dummy_structure = Strucutre{0.0, 0.0, weight};
auto range = std::equal_range(structures.cbegin(), structures.cend(),
dummy_structure, sort_structure_by_weight_asc);
if (range.first != structures.cend() && range.second != structures.cbegin()) {
// do whatever you want here
// if the `if`-condition isn't satisfied, no structure
// had weight `weight`.
}
}
如果需要修改structures向量中的元素,可以将std::equal_range和if条件调用中的cbegin和cend分别替换为begin/end .
备选方案 2:手工制作的函数对象
但是,我个人认为创建 dummy struct 不是很干净,所以让我们看看自定义函数对象如何改进代码。
函数对象本身可以定义为
struct ComparatorStructureToWeightAsc {
bool operator()(Structure const& s, double weight) const {
return s.weight < weight;
}
bool operator()(double weight, Structure const& s) const {
return weight < s.weight;
}
};
那么代码将如下所示:
std::sort(structures.begin(), structures.end(),
[](auto const& s1, auto const& s2) { return s1.weight < s2.weight; });
for (auto i = 0; i < 1000; ++i) {
auto weight = GetASpecificWeight();
auto range = std::equal_range(structures.cbegin(), structures.cend(),
weight, ComparatorStructureToWeightAsc);
if (range.first != structures.cend() && range.second != structures.cbegin()) {
// do whatever you want here
// if the `if`-condition isn't satisfied, no structure
// had weight `weight`.
}
}
备选方案 3:使用 Boost.Functional/OverloadedFunction
如您所见,我不擅长命名事物,因此必须命名用于将结构与权重进行比较的函数对象有点尴尬,特别是如果它只用于这个单一的地方。如果您有权访问 Boost,尤其是 Boost.Functional/OverloadedFunction,则可以使用两个 lambda,而不是手工制作的函数对象。
代码如下所示:
std::sort(structures.begin(), structures.end(),
[](auto const& s1, auto const& s2) { return s1.weight < s2.weight; });
for (auto i = 0; i < 1000; ++i) {
auto weight = GetASpecificWeight();
auto range = std::equal_range(structures.cbegin(), structures.cend(), weight,
boost::make_overloaded_function(
[](Structure const& s, double weight) { return s.weight < weight; },
[](double weight, Structure const& s) { return weight < s.weight; }));
if (range.first != structures.cend() && range.second != structures.cbegin()) {
// do whatever you want here
// if the `if`-condition isn't satisfied, no structure
// had weight `weight`.
}
}