To nie jest odpowiedź na konkretny problem, ale dobre obejście problemu, który prawdopodobnie próbujesz rozwiązać.
Wystąpił ten sam problem przy wdrażaniu ogólnego mechanizmu przekazywania. Moim rozwiązaniem było użycie wrappera na samym wywołaniu bindowania, specjalizującym się w odmianach. Chociaż nie rozwiązuje problemu, zdecydowanie minimalizuje nadmiarowy kod tylko do wywołania bindowania, a co najważniejsze daje mi system delegatów oparty na wariancie, którego mogę używać wszędzie.
template<class CALLBACK_TARGET_CLASS, typename RETURN_TYPE>
std::function<RETURN_TYPE()> BindFunction(RETURN_TYPE (CALLBACK_TARGET_CLASS::*memberFunction)(), CALLBACK_TARGET_CLASS* callbackTarget)
{
return std::bind(memberFunction, callbackTarget);
}
template<class CALLBACK_TARGET_CLASS, typename RETURN_TYPE, typename P0>
std::function<RETURN_TYPE()> BindFunction(RETURN_TYPE (CALLBACK_TARGET_CLASS::*memberFunction)(P0), CALLBACK_TARGET_CLASS* callbackTarget)
{
return std::bind(memberFunction, callbackTarget, std::placeholders::_1);
}
template<class CALLBACK_TARGET_CLASS, typename RETURN_TYPE, typename P0, typename P1>
std::function<RETURN_TYPE()> BindFunction(RETURN_TYPE (CALLBACK_TARGET_CLASS::*memberFunction)(P0, P1), CALLBACK_TARGET_CLASS* callbackTarget)
{
return std::bind(memberFunction, callbackTarget, std::placeholders::_1, std::placeholders::_2);
}
template<typename RETURNTYPE, typename... ARGS>
struct Delegate
{
std::function<RETURN_TYPE (ARGS...)> callbackFunction;
template<class CALLBACK_TARGET_CLASS>
void Bind(CALLBACK_TARGET_CLASS* callbackTarget, RETURN_TYPE (CALLBACK_TARGET_CLASS::*memberFunction)(ARGS...))
{
callbackFunction = BindFunction<CALLBACK_TARGET_CLASS, RETURN_TYPE, ARGS...>(memberFunction, callbackTarget);
}
void Callback(ARGS... params)
{
callbackFunction(params...);
}
};
Wykorzystanie kończy nam patrząc tak ..
class Foo
{
public:
void Bar(int x);
}
Foo foo;
Delegate<void, int> myDelegate;
myDelegate.Bind(&foo, &Foo::Bar);
myDelegate.Callback(3);
Istnieje dobra implementacja narzędzia make_indice tutaj: [http://preney.ca] (http://preney.ca/paul/2011/10/16/applying-stdtuple-to-functors-efficiently/) ale trudno mi się zastanowić, w jaki sposób mogę go użyć z boost :: arg <> – Blizter
Ten link był świetny do odczytu, a funkcja 'apply (Func, std :: tuple)' może być przydatna pewnego dnia . –
Widzę "nazwa_typu ... Args". Czy używasz C++ 11? – kennytm