按值的未排序std :: find和std :: any_of

nas*_*ver 5 c++ parallel-processing search find c++20

假设我有一个,std::vector<int>并且想知道它是否包含3或将迭代器添加到3

我不想使用std::setstd::multiset出于任何原因。

我想在std::execution::par_unseq模式下执行此操作。
我看到的两个选项是std::any_ofstd::find,但是它们对我来说不太合适。

#include <execution>
#include <functional>
#include <iostream>
#include <vector>

int main()
{
  std::vector vec{ 1, 1, 1, 1, 1, 3, 3, 3, 3 };

  bool contains{ std::any_of(
      std::execution::par_unseq,
      vec.begin(), vec.end(),
      std::bind(std::equal_to{}, std::placeholders::_1, 3)) };

  auto found{ std::find(std::execution::par_unseq, vec.begin(), vec.end(), 3) };

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

std::any_of应该做我想做的,但呼叫是他们做的非常凌乱。范围std::bind_front会有所帮助,但不是很多。

问题std::find在于它必须找到a 的第一次出现3,这限制了它的效率,因为我不在乎3它的发现。

  • 除了std::any_of按值搜索之外,还有其他选择吗?
  • 是否有std::find(和std::search)那找到任何匹配,而不是第一?

欢迎回答最多


编辑

为了澄清起见,我不需要一个函数来检查包含并同时给我一个迭代器。我正在寻找两个不同的函数(一个返回迭代器,一个返回布尔)。

Max*_*hof 2

我不太明白你认为 不好的地方any_of,特别是如果你使用 lambda 而不是圣歌std::bind

bool contains = std::any_of(std::execution::par_unseq,
                            vec.begin(), vec.end(),
                            [](auto elem) { return elem == 3; });
Run Code Online (Sandbox Code Playgroud)

(根据您的喜好分配换行符和空格...)


或者,如果这种情况很常见,您也可以自己定义一个仿函数对象,该对象采用要在构造函数中进行比较的值。或者,更方便的是,像这样:

template<class T>
auto equalTo(T value)
{
  return [value](auto other) { return other == value; };
}

// ...

bool contains = std::any_of(std::execution::par_unseq,
                            vec.begin(), vec.end(),
                            equalTo(3));
Run Code Online (Sandbox Code Playgroud)

至于类似的东西std::find_any在并行执行时利用提前取消:标准库中尚不存在这样的东西。串行版本显然是最佳的,通过在找到第一次出现时返回,但没有人去添加不同的算法来改进并行情况。对标准库的调用产生依赖于时间的结果(即使没有竞争)也是不常见的,所以我不会抱有希望。

我还要指出的是,当前的 MSVC 实现实际上执行了上面讨论的快速取消优化(它真正有多大帮助取决于分块策略,我一眼无法弄清楚)。因为clang真的什么也说不出来……