then
ハーブサッターが提案する機能も利用できます。これは、関数のわずかに変更されたバージョンです。それがどのように変更されたか、および元の話へのリンクについての詳細は、このSOの質問にあります。コードは次のように要約されます。
return then(std::move(component), [](Component c) { return Item(c); });
元々のアイデアはthen
、のメンバー関数としての機能を持つstd::future<T>
ことであり、それを標準化するためのいくつかの進行中の作業があります。関数の2番目のバージョンは、void
先物用です(基本的に関数を非同期にチェーンするだけです)。Herbが指摘したように、追加のスレッドが必要になる可能性があるため、このアプローチを使用することで料金を支払うことができます。
コードは次のようになります。
#include <future>
#include <thread>
#include <iostream>
template <typename T, typename Work>
auto then(std::future<T> f, Work w) -> std::future<decltype(w(f.get()))>
{
return std::async([](std::future<T> f, Work w)
{ return w(f.get()); }, std::move(f), std::move(w));
}
template <typename Work>
auto then(std::future<void> f, Work w) -> std::future<decltype(w())>
{
return std::async([](std::future<void> f, Work w) -> decltype(w())
{ f.wait(); return w(); }, std::move(f), std::move(w));
}
struct Component { };
struct Item {
Item(Component component) : comp(component) {}
Component comp;
};
struct Factory {
static std::future<Item> get_item() {
std::future<Component> component = get_component();
return then(std::move(component), [](Component c) { return Item(c); });
}
static std::future<Component> get_component()
{
return std::async([](){ return Component(); });
}
};
int main(int argc, char** argv)
{
auto f = Factory::get_item();
return 0;
}
上記のコードは、clangおよびlibc ++(Mac OS X 10.8でテスト済み)で正常にコンパイルされます。