#include <future>
#include <functional>
#include <type_traits>
#include <iostream>
void foo()
{
std::cout<<"Hello, world!"<<std::endl;
}
template<typename T> struct adv {
T t;
explicit adv(T &&t):t(std::forward<T>(t)) {}
template<typename ...U> T &&operator()(U &&...) {
return std::forward<T>(t);
}
};
template<typename T> adv<T> make_adv(T &&t) {
return adv<T>{std::forward<T>(t)};
}
namespace std {
template<typename T>
struct is_bind_expression< adv<T> > : std::true_type {};
}
int main()
{
typedef decltype(&foo) foo_type;
typedef std::result_of<foo_type()>::type foo_rettype;
auto chosen_async=
static_cast<std::future<foo_rettype> (*)(foo_type && )>(&std::async<foo_type>);
auto async_bound=
std::bind<std::future<foo_rettype>>(chosen_async,
make_adv(std::forward<foo_type>(&foo)));
async_bound().wait();
async_bound().wait();
}
I2luY2x1ZGUgPGZ1dHVyZT4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKdm9pZCBmb28oKQp7CiAgICBzdGQ6OmNvdXQ8PCJIZWxsbywgd29ybGQhIjw8c3RkOjplbmRsOwp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBzdHJ1Y3QgYWR2IHsgCiAgVCB0OyAKICBleHBsaWNpdCBhZHYoVCAmJnQpOnQoc3RkOjpmb3J3YXJkPFQ+KHQpKSB7fSAKICB0ZW1wbGF0ZTx0eXBlbmFtZSAuLi5VPiBUICYmb3BlcmF0b3IoKShVICYmLi4uKSB7IAogICAgcmV0dXJuIHN0ZDo6Zm9yd2FyZDxUPih0KTsgCiAgfSAKfTsgCgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPiBhZHY8VD4gbWFrZV9hZHYoVCAmJnQpIHsgCiAgcmV0dXJuIGFkdjxUPntzdGQ6OmZvcndhcmQ8VD4odCl9OyAKfQoKbmFtZXNwYWNlIHN0ZCB7IAogIHRlbXBsYXRlPHR5cGVuYW1lIFQ+IAogIHN0cnVjdCBpc19iaW5kX2V4cHJlc3Npb248IGFkdjxUPiA+IDogc3RkOjp0cnVlX3R5cGUge307IAp9IAoKaW50IG1haW4oKQp7CiAgICAgdHlwZWRlZiBkZWNsdHlwZSgmZm9vKSBmb29fdHlwZTsKICAgICB0eXBlZGVmIHN0ZDo6cmVzdWx0X29mPGZvb190eXBlKCk+Ojp0eXBlIGZvb19yZXR0eXBlOwoKICAgICBhdXRvIGNob3Nlbl9hc3luYz0KICAgICAgIHN0YXRpY19jYXN0PHN0ZDo6ZnV0dXJlPGZvb19yZXR0eXBlPiAoKikoZm9vX3R5cGUgJiYgKT4oJnN0ZDo6YXN5bmM8Zm9vX3R5cGU+KTsKCiAgICAgYXV0byBhc3luY19ib3VuZD0KICAgICAgICAgc3RkOjpiaW5kPHN0ZDo6ZnV0dXJlPGZvb19yZXR0eXBlPj4oY2hvc2VuX2FzeW5jLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFrZV9hZHYoc3RkOjpmb3J3YXJkPGZvb190eXBlPigmZm9vKSkpOwoKICAgICBhc3luY19ib3VuZCgpLndhaXQoKTsKICAgICBhc3luY19ib3VuZCgpLndhaXQoKTsKfQ==