Здравствуйте. Короче, получилось что-то такое:
using namespace md;
namespace md {
void add_to_queue(const std::function<void()>& fnc)
{
fnc(); // Для проверки просто вызываем
}
template<typename Sig>
struct defer_proxy
{
template<typename... Args>
void operator()(Args&&... args)
{
// Чтобы протащить в лямбду...
stdext::call_traits<Sig>::parameter_types args_tuple(std::forward<Args>(args)...); // Пакуем аргументы в туплу
auto fn_ = std::move(fn); // И функцию в локал
add_to_queue([fn_, args_tuple](){stdext::call_elements(fn_, args_tuple);}); // call_elements = std::apply
}
std::function<Sig> fn;
};
template<typename T>
auto defer(const T& fn) -> typename std::function<typename stdext::call_traits<T>::signature>
{
return defer_proxy<typename stdext::call_traits<T>::signature>{fn};
}
} // md
int main(int argc, char * argv[])
{
auto x = [](int i, float f)
{
std::cout << i << " " << f << std::endl;
};
defer(x)(1, 1.0f);
std::function<void(int, float)> y = x;
defer(y)(2, 2.0f);
return 0;
}
Запустить "как есть" его не получится (call_traits и call_elements), но, может, будут какие-то замечания просто при взгляде на него?