2015-12-09 4 views
0

Я пытаюсь реализовать простой решатель зависимостей с использованием std::future и std::async. То, что я не понимаю, это даже возможно сделать. Вопрос: можем ли мы пройти (пока не доступно) future до async позвонить? Если нет, то что можно сделать, чтобы иметь цепочку функций с некоторым еще не готов вход, вызывающий друг друга? Может быть, можно переопределить значение, переданное в отложенное async?Решатель зависимости с использованием std :: future и std :: async

Возможно, мое описание непостижимо, так вот пример:

#include <iostream> 
#include <future> 
#include <map> 

using namespace std; 

int adder(future<int> a, future<int> b) { 
    return a.get() + b.get(); 
} 

int main() { 
    map<char, future<int>> scheme; 

    scheme['c'] = future<int>(async(launch::deferred, [] { return 1;})); 
    scheme['a'] = future<int>(async(launch::deferred, adder, move(scheme['b']), move(scheme['c']))); 
    scheme['b'] = future<int>(async(launch::deferred, [] { return 3;})); 

    cout << scheme['a'].get() << endl; 
} 

Мы должны иметь схему так:

c 
    \ 
    a ----- result 
/
b 

И результат 4. Этот код не работает: move просто берет future и передает его adder. Если мы поменяем местами с 'a' и 'b', он будет работать нормально, но таким образом мы уже должны знать зависимости.

ответ

1

Используйте обещания. И, возможно, будущие фьючерсы.

template<class T> 
struct problem { 
    std::promise<std::shared_future<T>> p; 
    std::shared_future<std::shared_future<T>> f; 
    problem():f(p.get_future()){} 
    template<class W, class...Args> 
    void set(W&&work, Args&&...args){ 
    p.set_value(std::async(std::launch::deferred, std::forward<W>(work), std::forward<Args>(args)...)); 
    } 
    T get(){ 
    return f.get().get(); 
    } 
}; 

int adder(problem<int>& a, problem<int>& b) { 
    return a.get() + b.get(); 
} 
int main() { 
    std::map<char, problem<int>> scheme; 

    scheme['c'].set([] { return 1;}); 
    scheme['a'].set(adder, std::ref(scheme['b']), std::ref(scheme['c'])); 
    scheme['b'].set([] { return 3;}); 

    std::cout << scheme['a'].get() << '\n'; 
} 

Возможно, есть более простые способы.

live example.

+0

Спасибо, это действительно работает! Я понимаю почти всю магию будущего будущего и перспективы будущего. Вот рабочая версия кода: https://gist.github.com/JIghtuse/25960e886d97ac885f67 – JIghtuse

+0

@JIghtuse Добавлен живой пример. Я не уверен, могу ли я устранить будущую будущую проблему; возможно, путем явного хранения 'std :: function' в' problem', который будет установлен позже, и затем создания 'std :: shared_future', который вызывает эту функцию на отложенной основе? Хм, я думаю, что это сработает. Однако, если есть циклы, может получиться волосатое. – Yakk