So I wrote a function that composes "sequentially" void lambdas so that I can use them at once in an algorithm:
template <typename F, typename... Fs>
auto lambdaList(F f, Fs... fs)
{
return [=] (auto&... args) { f(args...); lambdaList(fs...)(args...); };
}
template <typename F>
auto lambdaList(F f)
{
return [=] (auto&... args) { f(args...); };
}
It works if I use local lambdas, but not when I use functions in a different namespace:
#include <iostream>
namespace foo {
void a() { std::cout << "a\n"; }
void b() { std::cout << "b\n"; }
}
template <typename F, typename... Fs>
auto lambdaList(F f, Fs... fs)
{
return [=] (auto&... args) { f(args...); lambdaList(fs...)(args...); };
}
template <typename F>
auto lambdaList(F f)
{
return [=] (auto&... args) { f(args...); };
}
int main() {
auto printStarBefore = [] (const std::string& str) {
std::cout << "* " + str;
};
auto printStarAfter = [] (const std::string& str) {
std::cout << str + " *" << std::endl;
};
lambdaList(printStarBefore, printStarAfter)("hi"); // ok
lambdaList(foo::a, foo::b)(); // error
}
The error is no matching function for call to 'lambdaList()' with:
main.cpp:11:56: note: candidate expects at least 1 argument, 0 provided
return [=] (auto&... args) { f(args...); lambdaList(fs...)(args...); };
~~~~~~~~~~^~~~~~~
Why does it sometimes work but sometimes not?
You need to invert your functions:
template <typename F>
auto lambdaList(F f)
{
return [=] (auto&... args) { f(args...); };
}
template <typename F, typename... Fs>
auto lambdaList(F f, Fs... fs)
{
return [=] (auto&... args) { f(args...); lambdaList(fs...)(args...); };
}
As-is, your base case won't be found by unqualified lookup in your recursive case - it can only be found by argument dependent lookup. If the arguments aren't in the same namespace as lambdaList, then it won't be found at all and the recursive step will always call itself. That's the source of your error.
The new ordering allows the base-case lambdaList() to be found by normal unqualified lookup - now it's visible at the point of definition of the recursive lambdaList().
That said, we can do better. Write one function that invokes everything:
template <typename... Fs>
auto lambdaList(Fs... fs) {
using swallow = int [];
return [=](auto const&... args) {
(void)swallow{0,
(void(fs(args...)), 0)...
};
};
}
And now we don't need to worry about any kind of lookup. If you have access to a modern-enough compiler that supports some C++1z features, the above can be greatly reduced with:
template <typename... Fs>
auto lambdaList(Fs... fs) {
return [=](auto const&... args) {
(fs(args...), ...);
};
}
That's downright understandable!
Related
related post: How to combine std::bind(), variadic templates, and perfect forwarding?
Is there a way to bind a function with variadic tuples ? Here incorrect code indicating the intent:
// t is an instance of T
auto f = std::bind(&T::iterate,t,???);
// args is an instance of std::tuple<Args...> args;
std::apply(f,args);
(note: I am unsure "variadic tuple" to be the right terminology. Looking forward editing the post with your correction)
Since C++20 you can use std::bind_front:
template<class T>
void print (T val) {
std::cout << val << std::endl;
}
struct T {
template<class ... Args>
void iterate(Args... args) {
int temp[] = { (print(args),0)... };
}
};
// all happens here
template<class ... Args>
void foo(const tuple<Args...>& args) {
T t;
auto f = std::bind_front(&T::iterate<Args...>,&t);
std::apply(f,args);
}
// the call
int i = 1;
foo(std::make_tuple(i,i+1,"bind is cool"));
If you want to use old std::bind, you can provide your own placeholders to be generated from pack:
template<int N>
struct MyPlaceholder {};
namespace std {
template<int N>
struct is_placeholder<MyPlaceholder<N>> : public integral_constant<int, N> {};
}
template<class ... Args, size_t ... Indices>
void foo2helper(const tuple<Args...>& args, std::index_sequence<Indices...>) {
T t;
auto f = std::bind(&T::iterate<Args...>,&t, (MyPlaceholder<Indices+1>{})...);
std::apply(f,args);
}
template<class ... Args>
void foo2(const tuple<Args...>& args) {
foo2helper(args, std::make_index_sequence<sizeof...(Args)>{});
}
// the call
foo2(std::make_tuple(2.34,"only bind"));
Live demo
Don't use bind, use a lambda instead:
auto f = [&t](auto... args){ t.iterate(args...); };
std::apply(f, args);
If you want perfect forwarding, that would look like:
auto f = [&t](auto&&... args){ t.iterate(std::forward<decltype(args)>(args)...); };
std::apply(f, args);
For a set of N functions fs... each taking only a single argument, I would like to create an object which has a call operator taking N arguments args..., calls all functions fs(args)... and returns outputs as a tuple.
The basic class would look something like this. I have marked the places I do not know how to implement with ???.
template <class... Fs>
struct merge_call_object {
merge_call_object(Fs... _fs)
: fs(std::move(_fs)...) {}
template <class... Args>
auto operator()(Args &&... args) -> decltype(???){
???
}
std::tuple<Fs...> fs;
};
The expected usage of this object would be:
auto f1 = [](double x){ return 2*s; };
auto f2 = [](std::string const& s){ return s+" World!"; };
auto mco = merge_call_object{f1,f2};
// The following should yield std::tuple{42, "Hello World!"}
auto out = mco(21, "Hello ");
So far so good, doing the above is "easy" but I want that overloading for mco works as expected i.e. the following should compile and pass
static_assert(std::is_invocable_v<decltype(mco), double, std::string> == true);
static_assert(std::is_invocable_v<decltype(mco), double, double> == false);
The biggest challenge I see is how implement correctly the SFINAE -> decltype(???).
This question is inspired by the recent talk from CppCon Overloading: The Bane of All Higher-Order Functions, around 6:40 he talks about how to wrap a function into a lambda.
My implementation without the correct overload set, plus a small test on perfect forwarding.
#include <iostream>
#include <tuple>
#include <utility>
namespace detail {
template <std::size_t... I>
constexpr auto integral_sequence_impl(std::index_sequence<I...>) {
return std::make_tuple((std::integral_constant<std::size_t, I>{})...);
}
template <std::size_t N, typename Indices = std::make_index_sequence<N>>
constexpr auto integral_sequence = integral_sequence_impl(Indices{});
template <std::size_t N, typename Fun>
constexpr decltype(auto) apply_sequence(Fun &&fun) {
return std::apply(std::forward<Fun>(fun), detail::integral_sequence<N>);
}
} // namespace detail
template <class... Fs>
struct merge_call_object {
merge_call_object(Fs... _fs)
: fs(std::move(_fs)...) {}
template <class... Args>
auto operator()(Args &&... args) {
constexpr int N = sizeof...(Fs);
auto f = [&](auto I) { return std::get<I>(fs); };
auto arg = [&](auto I) -> decltype(auto) {
return std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...));
};
return detail::apply_sequence<N>(
[&](auto... Is) { return std::forward_as_tuple(f(Is)(arg(Is))...); });
}
std::tuple<Fs...> fs;
};
struct Screamer {
Screamer() { std::cout << "Constructor!" << std::endl; }
Screamer(Screamer &&s) { std::cout << "Move constructor!" << std::endl; }
Screamer(Screamer const &s) { std::cout << "Copy constructor!" << std::endl; }
};
int main() {
auto f1 = [](auto &&x) -> decltype(auto) {
std::cout << "Calling f1" << std::endl;
return std::forward<decltype(x)>(x);
};
auto f2 = [](auto &&x) -> decltype(auto) {
std::cout << "Calling f2" << std::endl;
return std::forward<decltype(x)>(x);
};
auto mco = merge_call_object{f1, f2};
auto [s1, s2] = mco(Screamer{}, Screamer{});
return 0;
}
Since you have a direct one argument, one function mapping, all you really need is std::apply:
template <class... Args>
auto operator()(Args&&... args) {
return std::apply([&](Fs&... fs){
return std::tuple(fs(std::forward<Args>(args))...);
}, fs);
}
This will decay all of the types (that is, if some function/argument pair actually returns an int&, this will give you an int in that spot instead). This also isn't SFINAE-friendly.
A solution that is both SFINAE-friendly and maintains references just needs an extra dash of fold-expression:
template <class... Args,
std::enable_if_t<(std::is_invocable_v<Fs&, Args> && ...), int> = 0>
auto operator()(Args&&... args) {
return std::apply([&](Fs&... fs){
return std::tuple<std::invoke_result_t<Fs&, Args>...>(
fs(std::forward<Args>(args))...);
}, fs);
}
You have to use auto f() -> decltype(RET) { return RET; } way (Macro can be used to avoid the boiler plate :-/ and we can also handle noexcept).
Something like:
template <class... Fs>
struct merge_call_object {
private:
std::tuple<Fs...> fs;
private:
template <std::size_t... Is, typename Tuple>
auto call(std::index_sequence<Is...>, Tuple&& tuple)
-> decltype(std::make_tuple(std::get<Is>(fs)(std::get<Is>(std::forward<Tuple>(tuple)))...))
{
return std::make_tuple(std::get<Is>(fs)(std::get<Is>(std::forward<Tuple>(tuple)))...);
}
public:
merge_call_object(Fs... _fs)
: fs(std::move(_fs)...) {}
template <class... Args>
auto operator()(Args &&... args)
-> decltype(call(std::index_sequence_for<Fs...>(), std::forward_as_tuple(std::forward<Args>(args)...)))
{
return call(std::index_sequence_for<Fs...>(), std::forward_as_tuple(std::forward<Args>(args)...));
}
};
Demo
Given two or more example functions, is it possible to write templated code which would be able to deduce the arguments of a function provided as a template parameter?
This is the motivating example:
void do_something(int value, double amount) {
std::cout << (value * amount) << std::endl;
}
void do_something_else(std::string const& first, double & second, int third) {
for(char c : first)
if(third / c == 0)
second += 13.7;
}
template<void(*Func)(/*???*/)>
struct wrapper {
using Args = /*???*/;
void operator()(Args&& ... args) const {
Func(std::forward<Args>(args)...);
}
};
int main() {
wrapper<do_something> obj; //Should be able to deduce Args to be [int, double]
obj(5, 17.4); //Would call do_something(5, 17.4);
wrapper<do_something_else> obj2; //Should be able to deduce Args to be [std::string const&, double&, int]
double value = 5;
obj2("Hello there!", value, 70); //Would call do_something_else("Hello there!", value, 70);
}
In both uses of /*???*/, I am trying to work out what I could put there that would enable this kind of code.
The following doesn't appear to work, due to Args not being defined before its first use (along with what I have to assume are numerous syntax errors besides), and even if it did, I'm still looking for a version that doesn't require explicit writing of the types themselves:
template<void(*Func)(Args ...), typename ... Args)
struct wrapper {
void operator()(Args ...args) const {
Func(std::forward<Args>(args)...);
}
};
wrapper<do_something, int, double> obj;
With C++17 we can have auto template non-type parameters which make possible the Wrapper<do_something> w{} syntax 1).
As for deducing Args... you can do that with a specialization.
template <auto* F>
struct Wrapper {};
template <class Ret, class... Args, auto (*F)(Args...) -> Ret>
struct Wrapper<F>
{
auto operator()(Args... args) const
{
return F(args...);
}
};
Wrapper<do_something> w{};
w(10, 11.11);
1) Without C++17 it's impossible to have the Wrapper<do_something> w{} nice syntax.
The best you can do is:
template <class F, F* func>
struct Wrapper {};
template <class Ret, class... Args, auto (*F)(Args...) -> Ret>
struct Wrapper<Ret (Args...), F>
{
auto operator()(Args... args) const
{
return F(args...);
}
};
Wrapper<declype(do_something), do_something> w{};
With C++17, you can do this:
template <auto FUNC, typename = decltype(FUNC)>
struct wrapper;
template <auto FUNC, typename RETURN, typename ...ARGS>
struct wrapper<FUNC, RETURN (*)(ARGS...)> {
RETURN operator()(ARGS ...args) {
return FUNC(args...);
}
};
I've learned this technique from W.F.'s answer
Further improvement of C++17 version: less template parameters and proper noexcept annotation:
template<auto VFnPtr> struct
wrapper;
template<typename TResult, typename... TArgs, TResult ( * VFnPtr)(TArgs...)> struct
wrapper<VFnPtr>
{
TResult
operator ()(TArgs... args) const noexcept(noexcept((*VFnPtr)(::std::forward<TArgs>(args)...)))
{
return (*VFnPtr)(::std::forward<TArgs>(args)...);
}
};
With C++11 you can consider a templated make_wrapper helper function. However, with this approach the function pointer is not a template parameter. Instead, the function pointer is "carried" by the non-static data member called f_ in the following example:
#include <iostream>
void do_something(int value, double amount) {
std::cout << (value * amount) << std::endl;
}
void do_something_else(std::string const& first, double & second, int third) {
for(char c : first)
if(third / c == 0)
second += 13.7;
}
template<class Ret, class... Args>
using function_pointer = Ret(*)(Args...);
template<class Ret, class... Args>
struct wrapper {
using F = function_pointer<Ret, Args...>;
F f_;
explicit constexpr wrapper(F f) noexcept : f_{f} {}
template<class... PreciseArgs>// not sure if this is required
Ret operator()(PreciseArgs&&... precise_args) const {
return f_(std::forward<PreciseArgs>(precise_args)...);
}
};
template<class Ret, class... Args>
constexpr auto make_wrapper(
function_pointer<Ret, Args...> f
) -> wrapper<Ret, Args...> {
return wrapper<Ret, Args...>(f);
}
int main() {
constexpr auto obj = make_wrapper(do_something);
obj(5, 17.4);
constexpr auto obj2 = make_wrapper(do_something_else);
double value = 5;
obj2("Hello there!", value, 70);
return 0;
}
I am trying to create a wrapper that calls std::terminate() when it catch an exception.
I would like this wrapper to take the same arguments as std::async() (it could be a call to a function as well as a call to a method).
Someone know how to make this code to compile ?
Thank you
http://ideone.com/tL7mTv
#include <iostream>
#include <functional>
#include <future>
template<class Fn, class... Args>
inline auto runTerminateOnException(Fn&& fn, Args&&... args) {
try {
return std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...)();
} catch (...) {
std::terminate();
}
}
template<class Fn, class... Args>
inline auto runAsyncTerminateOnException(Fn&& fn, Args&&... args) {
return std::async(std::launch::async, runTerminateOnException<Fn, Args&&...>, std::forward<Fn>(fn), std::forward<Args>(args)...);
}
struct Foo {
void print() {
printf("Foo::print()\n");
}
};
int main() {
Foo foo;
std::future<void> future = runAsyncTerminateOnException(&Foo::print, &foo);
// your code goes here
return 0;
}
I personally think you over complicated it a bit. You can just bind the call and use a simple lambda to do the wrapping.
#include <iostream>
#include <future>
#include <functional>
#include <type_traits>
template<class Fn, class... Args>
inline auto runAsyncTerminateOnException(Fn&& fn, Args&&... args) {
auto make_call = std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...);
return std::async(std::launch::async, [=]() -> decltype(make_call()) {
try {
return make_call();
} catch (...) {
std::cout << "Terminate Called!" << std::endl;
std::terminate();
}
});
}
struct Foo {
void print() {
printf("Foo::print()\n");
}
void print2() {
printf("Foo::print2()\n");
throw 1;
}
};
int main() {
Foo foo;
std::future<void> future = runAsyncTerminateOnException(&Foo::print, &foo);
std::future<void> future2 = runAsyncTerminateOnException(&Foo::print2, &foo);
return 0;
}
See it live, with possible output.
I obviously copied the first closure instead of preforming the required step to move it into the second closure (as one would do in c++11). You can of course move it with a specific move capture in c++14.
In c++17, the clean way to do this will be to use std::invoke.
I have hacked it in here to demonstrate.
#include <iostream>
#include <future>
#include <functional>
#include <type_traits>
namespace std
{
template<class T>
static constexpr bool is_member_pointer_v = std::is_member_pointer<T>::value;
template<class T>
static constexpr bool is_function_v = std::is_function<T>::value;
template<class B, class T>
static constexpr bool is_base_of_v = std::is_base_of<B, T>::value;
namespace detail {
template <class T>
struct is_reference_wrapper : std::false_type {};
template <class U>
struct is_reference_wrapper<std::reference_wrapper<U>> : std::true_type {};
template <class T>
constexpr bool is_reference_wrapper_v = is_reference_wrapper<T>::value;
template <class Base, class T, class Derived, class... Args>
auto INVOKE(T Base::*pmf, Derived&& ref, Args&&... args)
noexcept(noexcept((std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...)))
-> std::enable_if_t<std::is_function_v<T> &&
std::is_base_of_v<Base, std::decay_t<Derived>>,
decltype((std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...))>
{
return (std::forward<Derived>(ref).*pmf)(std::forward<Args>(args)...);
}
template <class Base, class T, class RefWrap, class... Args>
auto INVOKE(T Base::*pmf, RefWrap&& ref, Args&&... args)
noexcept(noexcept((ref.get().*pmf)(std::forward<Args>(args)...)))
-> std::enable_if_t<std::is_function_v<T> &&
is_reference_wrapper_v<std::decay_t<RefWrap>>,
decltype((ref.get().*pmf)(std::forward<Args>(args)...))>
{
return (ref.get().*pmf)(std::forward<Args>(args)...);
}
template <class Base, class T, class Pointer, class... Args>
auto INVOKE(T Base::*pmf, Pointer&& ptr, Args&&... args)
noexcept(noexcept(((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...)))
-> std::enable_if_t<std::is_function_v<T> &&
!is_reference_wrapper_v<std::decay_t<Pointer>> &&
!std::is_base_of_v<Base, std::decay_t<Pointer>>,
decltype(((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...))>
{
return ((*std::forward<Pointer>(ptr)).*pmf)(std::forward<Args>(args)...);
}
template <class Base, class T, class Derived>
auto INVOKE(T Base::*pmd, Derived&& ref)
noexcept(noexcept(std::forward<Derived>(ref).*pmd))
-> std::enable_if_t<!std::is_function_v<T> &&
std::is_base_of_v<Base, std::decay_t<Derived>>,
decltype(std::forward<Derived>(ref).*pmd)>
{
return std::forward<Derived>(ref).*pmd;
}
template <class Base, class T, class RefWrap>
auto INVOKE(T Base::*pmd, RefWrap&& ref)
noexcept(noexcept(ref.get().*pmd))
-> std::enable_if_t<!std::is_function_v<T> &&
is_reference_wrapper_v<std::decay_t<RefWrap>>,
decltype(ref.get().*pmd)>
{
return ref.get().*pmd;
}
template <class Base, class T, class Pointer>
auto INVOKE(T Base::*pmd, Pointer&& ptr)
noexcept(noexcept((*std::forward<Pointer>(ptr)).*pmd))
-> std::enable_if_t<!std::is_function_v<T> &&
!is_reference_wrapper_v<std::decay_t<Pointer>> &&
!std::is_base_of_v<Base, std::decay_t<Pointer>>,
decltype((*std::forward<Pointer>(ptr)).*pmd)>
{
return (*std::forward<Pointer>(ptr)).*pmd;
}
template <class F, class... Args>
auto INVOKE(F&& f, Args&&... args)
noexcept(noexcept(std::forward<F>(f)(std::forward<Args>(args)...)))
-> std::enable_if_t<!std::is_member_pointer_v<std::decay_t<F>>,
decltype(std::forward<F>(f)(std::forward<Args>(args)...))>
{
return std::forward<F>(f)(std::forward<Args>(args)...);
}
} // namespace detail
template< class F, class... ArgTypes >
auto invoke(F&& f, ArgTypes&&... args)
// exception specification for QoI
noexcept(noexcept(detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...)))
-> decltype(detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...))
{
return detail::INVOKE(std::forward<F>(f), std::forward<ArgTypes>(args)...);
}
}
template<class Fn, class... Args>
inline auto runAsyncTerminateOnException(Fn&& fn, Args&&... args) {
return std::async(std::launch::async, [=]() -> decltype(auto) {
try {
return std::invoke(fn, args...);
} catch (...) {
std::cout << "Terminate Called!" << std::endl;
std::terminate();
}
});
}
struct Foo {
void print() {
printf("Foo::print()\n");
}
void print2() {
printf("Foo::print2()\n");
throw 1;
}
};
int main() {
Foo foo;
std::future<void> future = runAsyncTerminateOnException(&Foo::print, &foo);
std::future<void> future2 = runAsyncTerminateOnException(&Foo::print2, &foo);
return 0;
}
error when invoking templated member function:
The error is this <source>: In instantiation of 'runAsyncTerminateOnException(Fn&&, Args&& ...)::<lambda()> [with Fn = void (Foo::*)(int&&); Args = {Foo*, int}]':
implying that Foo::print is demanding an int&& of course it is. That's what you wrote:
void print(Args&&... args)
It's not reasonable for a print function to demand ownership of objects. Declare it as it should be:
struct Foo {
template<class... Args>
void print(const Args&... args) {
printf("Foo::print(%d)\n", args...);
}
};
I found the solution for c++17.
It works only if we do not use auto for the return type of runTerminateOnException().
template<class Fn, class... Args>
inline std::result_of_t<Fn&&(Args&&...)> runTerminateOnException(Fn&& fn, Args&&... args) {
try {
return std::invoke(std::forward<Fn>(fn), std::forward<Args>(args)...);
} catch (...) {
std::terminate();
}
}
template<class Fn, class... Args>
inline auto runAsyncTerminateOnException(Fn&& fn, Args&&... args) {
return std::async(std::launch::async, runTerminateOnException<Fn, Args&&...>, std::forward<Fn>(fn), std::forward<Args>(args)...);
}
I am trying to write code to do something similar (code written for demonstration purposes) to this:
template <typename F, typename Args...>
inline auto runFunc(F func) -> foo
{
return foo([func](Args... args) -> std::result_of<F>::type
{
// Do something before calling func
func(args...);
// Do something after call func
});
}
So basically I am trying to write a function that returns an object that takes lambda that matches the templated function type. Obviously this code won't work because I do not have Args... defined. How would I solve this in C++11?
template<class F_before, class F, class F_after>
struct decorate_func_t {
F_before f0;
F f1;
F_after f2;
template<class...Args>
typename std::result_of<F(Args...)>::type operator()(Args&&...args)const{
f0();
auto r = f1(std::forward<Args>(args)...);
f2();
return r;
}
};
template<class F_before, class F, class F_after>
decorate_func_t<F_before, F, F_after>
decorate_func( F_before before, F f, F_after after ){
return {std::move(before), std::move(f), std::move(after)};
}
Then:
template <typename F, typename Args...>
inline auto runFunc(F func) -> foo
{
return foo(decorate_func(
[]{/* Do something before calling func */},
func,
[]{/* Do something after call func */ }
};
}
the lack of auto parameters in C++11 lambdas makes this about the best you can do.
In C++14 this is trivial:
template <class F>
auto runFunc(F func)
{
return foo(
[func](auto&&... args) // ->decltype(auto) maybe
{
// Do something before calling func
auto r = func(decltype(args)(args)...);
// Do something after call func
return r;
}
);
}
note that many nominally C++11 compilers actually support auto parameters on lambdas.
You can use a support structure as in the following example:
#include<type_traits>
#include<cassert>
struct foo {
template<typename F>
foo(F f) { assert(42 == f(42)); }
};
template<typename>
struct S;
template<typename R, typename... Args>
struct S<R(*)(Args...)> {
template <typename F>
static auto runFunc(F func) -> foo
{
return foo{[func](Args... args) -> R
{
// Do something before calling func
auto r = func(args...);
// Do something after call func
return r;
}};
}
};
template<typename F>
inline auto runFunc(F func) -> foo
{
return S<F>::runFunc(func);
}
int f(int i) { return i; }
int main() {
runFunc(f);
}
For it's not clear to me what's the context of the problem, I'm not sure I got exactly what you were asking for.
I hope the code above can help you.
Still being unsure it this is what you're searching for, I risk posting:
#include <iostream>
struct foo
{
template<typename T>
foo(T lambda)
{
lambda(1, 2);
}
};
template <typename F, typename... Args>
inline typename std::result_of<F>::type runFunc(F func)
{
return foo(
[func](Args... args)
{
std::cout << "Before";
func(args...);
std::cout << "After";
}
);
}
struct print
{
void operator()(int i) const
{
std::cout << i << std::endl;
}
void operator()(int i, int j) const
{
std::cout << i << " " << j << std::endl;
}
};
int main()
{
runFunc<print, int, int>(print());
}