Code:
#include <functional>
// A function template that takes an std::function and its arguments as
// parameters. We'll make it simple, but, in reality, it would use "func" to
// do something complicated with the contents of "one" and "two".
template< class One,
class Two,
class... More
>
int wrapper(std::function<int(One const&, Two const&, More...)> const& func,
One const& one,
Two const& two,
More... more)
{
return 2*func(one, two, more...);
}
// A couple of function templates, to be used in place of "func" above.
// The first two arguments must have public int value() functions.
template<class One, class Two>
int
wrap_this2(One const& one, Two const& two)
{
return one.value() + two.value();
}
template<class One, class Two, class Three>
int
wrap_this3(One const& one, Two const& two, Three three)
{
return one.value() + two.value() + three;
}
// Two PODS classes, with public int value() functions, to be used as
// arguments of the above function templates
class PODS1
{
int i;
public: PODS1(int _i) : i(_i) { };
int value() const { return i; }
};
class PODS2
{
int i;
public: PODS2(int _i) : i(_i) { };
int value() const { return i; }
};
// Main class.
class MainClass
{
int i;
// Embedded std::functions that wrap two specializations of wrap_this2/3
// in a form that can go straight to the argument list of "wrapper".
std::function<int(PODS1 const&,
PODS2 const&)
>
embed_wrap_this2 { wrap_this2<PODS1, PODS2> } ;
//embed_wrap_this2 = wrap_this2<PODS1, PODS2> ; // HERE
std::function<int(PODS1 const&,
PODS2 const&,
int)
>
embed_wrap_this3 { wrap_this3<PODS1, PODS2, int> } ;
public:
int member_func(int choose)
{
PODS1 first(1);
PODS2 second(2);
int third = 3;
// Case 4 is the same as case 2 but without the embedded function
switch(choose)
{
case 2:
return wrapper<PODS1, PODS2>(embed_wrap_this2, first, second);
case 3:
return wrapper<PODS1, PODS2, int>
(embed_wrap_this3, first, second, third);
case 4:
return wrapper<PODS1, PODS2>
(std::function<int(PODS1 const&, PODS2 const&)>
(wrap_this2<PODS1, PODS2>),
first, second);
default:
return 0;
}
}
};
#include <cstdio>
int main()
{
MainClass obj;
printf("%d %d %d\n", obj.member_func(2),
obj.member_func(3),
obj.member_func(4));
}