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

Is std::set<std::future> impossible to exist

本文关键字:std 不可能 存在 gt lt set future      更新时间:2023-10-16

我正在使用C 11进行一些线程程序。
现在我得到了这样的情况:

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

但是,当我尝试获取字符串时,我会遇到一个错误:

将XXX作为XXX丢弃限定符的"此"参数

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

如果我是对的,这是否意味着我永远无法声明std::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!!!
    }
}

当想到要使用的容器时,您应该想到"我可以使用std::vector执行此操作吗?"。如果您的答案是否定的,您应该问:"不,真的,我可以使用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;
  }     
}

实例示例

使用std::set进行此操作既是一个不好又不可能的想法。

一个坏主意,因为std::set是一个基于节点的容器,它确实努力维护排序顺序。我们不需要节点。我们不需要排序订单。因此,我们使用的是一个比我们需要的更强大的容器。

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

不可能,因为std::future不提供operator<,也没有合理的位置 Hook 在它们上提供了用户提供的比较功能。

请注意,shared_future S具有const get()方法,因此可以以不可变的方式存储。但是它们仍然没有为用户提供的订购操作提供"钩子"。