2015-09-15 52 views
6

Bağlamİleri üye işlevi

Temelde ben bind, function vb kullanamazsınız anlamına gelir (yani üçüncü bir kütüphaneye geçti gerektiğinden, üye işlev için bir const void *const olması gerekir). Bu imkansız gibi göründüğü için, bir sonraki en iyi şeyi yapmak ve bir üye işlevini statik bir yönlendirme yöntemiyle eşlemek istedim, daha sonra işaretçiyi (this ilk argüman olarak geçerek) elde edebilirim. Soru

ben farklı imzalarla, kayıt için gereken fonksiyonları bir sürü var, bu yüzden beni içine üyesi fonksiyonunun bir imza dönüştürmek için izin veren bir güzel bir çözüm istiyorum Statik bir yöntem imzası ('u bir argüman olarak geçirerek) - const void* const'a gönderim yapabilirim. Böylece temelde böyle bir şey yapmak istiyorum:

Yani temelde:

struct Foo 
{ 
    MyType Bar(int a); 
}; 

template <typename Ret, typename This, Ret(This::*Func)()> 
struct CallWrap0 
{ 
    static Ret &&Call(This* thisPtr) 
    { 
     return thisPtr->(*Func)(); 
    } 
}; 

int Main() 
{ 
    const void * const memberFunction = &(CallWrap0<MyType, Foo, Foo::Bar>()::Call); 
    // etc. 
} 

Bu çözüm sorun olduğunu - çalıştığını rağmen - Ben açıkça derleyici anlatmak zorunda çünkü, hiç hoş değil türleri. Derleyicinin tüm sıhhi tesisatları otomatik olarak doldurabileceği bir çözüm arıyorum. Yukarıda derlenmeyecektir MSVC için

template <class Ret, class T, class... Args> 
const void* const FunctionPtr(Ret (T::*function)(Args... args)) 
{ 
    // not sure... function is not a template, so this would require a class instance 
    // which is not possible due to the ext. library constraints. 
} 

cevap

4
#include <utility> 

template <typename T, T t> 
struct CallWrap; 

template <typename Ret, typename This, typename... Args, Ret(This::*Func)(Args...)> 
struct CallWrap<Ret(This::*)(Args...), Func> 
{ 
    static Ret Call(This* thisPtr, Args... args) 
    { 
     return (thisPtr->*Func)(std::forward<Args>(args)...); 
    } 
}; 

int main() 
{ 
    auto f = &CallWrap<decltype(&Foo::Bar), &Foo::Bar>::Call; 
} 

DEMO


: Şimdiye kadar şans olmadan, bir yardımcı fonksiyonu ile bu geçici bir çözüm girişimi oldum

Çözüm, aşağıdaki kodu deneyin:

template <typename T> 
struct CallWrap; 

template <typename Ret, typename This, typename... Args> 
struct CallWrap<Ret(This::*)(Args...)> 
{ 
    template <Ret(This::*Func)(Args...)> 
    struct Function 
    { 
     static Ret Call(This* thisPtr, Args... args) 
     { 
      return (thisPtr->*Func)(std::forward<Args>(args)...); 
     } 
    }; 
}; 

int main() 
{ 
    auto f = &CallWrap<decltype(&Foo::Bar)>::Function<&Foo::Bar>::Call; 
} 

DEMO 2

+0

Nice, 'decltype' kullanmayı düşünmezdim. Bence işe yarayacak. – atlaste

+0

@atlaste Güncellemeye bakın –

+0

Harika, sadece test ettim, gayet iyi çalışıyor. Bunu memnuniyetle kabul ediyorum, çok teşekkürler! – atlaste