std::set<std::future> 不可能存在吗

Yve*_*ves 0 c++ multithreading future set c++11

我正在使用 C++11 来做一些线程程序。
现在我遇到这样的情况:

我有一个std::set<std::future<std::string>> results存储线程的一些结果,当然所有这些线程都会返回一个字符串。

但是,当我尝试获取字符串时,出现以下错误:

将 xxx 作为 xxx 的“this”参数传递会丢弃限定符

根据此链接,我认为这是因为我试图调用属于 元素的非常量函数set。换句话说, the 的元素setstd::future<std::string>并且std::future<std::string>::get()是非常量。这就是为什么我收到这样的错误。

如果我是对的,这是否意味着我永远不能声明 astd::set<std::future>因为它get总是不可用?

这是我的代码:

set<future<string>> results;
results.insert(...); // insert some future
for(auto it = results.begin(); it != results.end();)
{
    if (it->wait_for(std::chrono::seconds(0)) == std::future_status::ready)
    {
        string tmp = it->get();  // ERROR!!!
    }
}
Run Code Online (Sandbox Code Playgroud)

Yak*_*ont 5

当考虑使用什么容器时,您应该思考“我可以用 a 来做这个吗std::vector?”。如果你的答案是否定的,你应该问“不,真的,我可以用 a 来做这个吗std::vector?”。

using namespace std::literals;
std::vector<std::future<std::string>> results;
constexpr auto threads = 10;
for (int i = 0; i < threads; ++i) {
  results.push_back( std::async( std::launch::async,
    [i]{
      std::this_thread::sleep_for( std::chrono::milliseconds((threads-i)%(threads/3)) );
      std::stringstream ss;
      ss << "hello world " << i;
      return ss.str();
    }
  ) );
}
for (auto it = results.begin(); it != results.end();) {
  if (it->wait_for( 0s ) == std::future_status::ready) {
    std::string tmp = it->get();
    std::cout << tmp << "\n";
    std::swap( *it, results.back() );  // noop if already at back
    if (std::next(it)==results.end()) it = results.begin(); // do this before pop back
    results.pop_back(); // Or this could invalidate it
    if (results.begin()==results.end()) break; // empty vector has to be caught early, as it is invalidated if vector is now empty
    continue;
  } else {
    ++it;
    if (it == results.end()) it = results.begin();
    continue;
  }     
}
Run Code Online (Sandbox Code Playgroud)

实例

用 a 来做这件事std::set既是一个坏主意,也是不可能的主意。

这是一个坏主意,因为std::set基于节点的容器会努力维护排序顺序。我们不需要节点。我们不需要排序顺序。所以我们使用的容器比我们需要的更强大。

不可能,因为 的内容std::set在设计上是不可变的。

不可能,因为std::future没有提供operator<,也没有合理的地方可以将用户提供的比较函数挂接到它们上。

请注意,shared_futures 有一个const get()方法,因此它们可以以不可变的方式存储。但他们仍然没有为用户提供的排序操作提供“钩子”。

  • 那些“继续”似乎是多余的 (3认同)