Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I put futures in a container?

I'm trying to put the futures generated by async in a vector, so I don't have to do something like:

auto f1 = async(....);
auto f2 = async(....);
...
f1.get();
f2.get();
...

The compilation error I am receiving with this code is "Call to deleted constructor of 'std::_1::future". Can anyone help me with how to do this properly. Not sure about copying the future's into the vector either.

void AudioAnalyzer::retrieve()
{
    deque<shared_ptr<AudioAnalysis>>tempData(data);
    vector<future<void>> futures;
    for (int i = 0; i < NUM_THREADS; ++i)
    {
        auto f = async(bind(&AudioAnalyzer::analysisThread, this, _1), ref(tempData));
        futures.push_back(f);
    }

    for (auto& f : futures)
    {
        f.get();
    }

}

void AudioAnalyzer::analysisThread(deque<shared_ptr<AudioAnalysis>>& aq )
{

    while (true)
    {
        m.lock();
        if (aq.size() == 0)
        {
            m.unlock();
            break;
        }
        auto aa = aq.front();
        aq.pop_front();
        m.unlock();

        if (false) //testing
        {
            retrieveFromDb(aa);
        }
        else
        {
            analyzeAudio(aa);
        }
    }
}
like image 227
Steve M Avatar asked May 04 '14 15:05

Steve M


People also ask

How does STD future work?

The class template std::future provides a mechanism to access the result of asynchronous operations: An asynchronous operation (created via std::async, std::packaged_task, or std::promise) can provide a std::future object to the creator of that asynchronous operation.

How do futures work in C++?

The basic principle behind async and futures is that called functions are run on another thread, and the return values are converted to what is called a future-value. Such future-values don't hold a real value until the asynchronous function ends.


2 Answers

If you are using C++11, you can also use the new emplace_back operator of std::vector like so:

futures.emplace_back(std::async(std::launch::async, f));

This will construct the std::future object in-place (directly into the std::vector) and thus avoid having to copy or move the future.

See http://en.cppreference.com/w/cpp/container/vector/emplace_back

like image 93
MathiasStokholm Avatar answered Oct 04 '22 13:10

MathiasStokholm


Futures are not copyable, but they are move-copyable. You need to move them into the container:

futures.push_back(std::move(f));

Here, std::move(f) looks like an rvalue, resulting in the right std::vector<future<void>>::push_back overload being selected.

like image 31
juanchopanza Avatar answered Oct 04 '22 11:10

juanchopanza