2014-05-19 134 views
2
template<typename T> struct A 
{ 
    static T x(T, T) { } 
    static T y(T, T) { } 
}; 

template<typename T> struct B 
{ 
    static T x(T, T) { } 
    static T y(T, T) { } 
}; 

struct Dispatcher 
{ 
    template<template<typename> class TC, ??? TStaticFunc, 
      typename T1, typename T2> 
    static std::common_type_t<T1, T2> call(T1 mI, T2 mJ) 
    { 
     return TC<std::common_type_t<T1, T2>>::*TStaticFunc(mI, mJ); 
    } 
}; 

Dispatcher::call<A, x>(12.f, 5); 
Dispatcher::call<B, x>(1.f, 51); 
Dispatcher::call<A, y>(2.f, 25); 
Dispatcher::call<B, y>(5.f, 3); 

是否可以創建類似Dispatcher::call的模板化函數? 我想分別傳遞類類型和靜態函數名稱。傳遞靜態成員函數作爲模板參數

或正在通過A<..:>::x實現這種調度的唯一可能方式?

+1

即使你將'???'替換爲'??? TStaticFunc'編譯器不知道你是在實例化Dispatcher :: call 時意味着什麼'x'。編譯器沒有'x' – borisbn

回答

5

那麼,如果你真的真的想,你可以做到。您只需爲每個靜態函數名稱定義一個類型,一個函數或一個變量(基本上是編譯時唯一的東西)。選項這一個:

namespace detail 
{ 
    template <typename T> 
    struct x 
    { 
     static decltype(&T::x) get() { return &T::x; } 
    }; 

    template <typename T> 
    struct y 
    { 
     static decltype(&T::y) get() { return &T::y; } 
    }; 

    // etc, you can use macros here to avoid boilerplate 
} 

現在改變Dispatcher有點...

struct Dispatcher 
{ 
    template<template<typename> class TC, template<typename> class FuncGetter, 
     typename T1, typename T2> 
     static typename std::common_type<T1, T2>::type call(T1 mI, T2 mJ) 
    { 
     typedef TC<typename std::common_type<T1, T2>::type> T; 
     auto staticMemberFunc = FuncGetter<T>::get(); 
     return staticMemberFunc(mI, mJ); 
    } 
}; 

而且現在下面的代碼:

using namespace detail; 
Dispatcher::call<A, x>(12.f, 5); 
Dispatcher::call<B, x>(1.f, 51); 
Dispatcher::call<A, y>(2.f, 25); 
Dispatcher::call<B, y>(5.f, 3); 

作品。如果您決定遵循這種模式,我建議您將xy更改爲​​或沿着這些方向。

或者,您可以寫一個宏來代替Dispatcher::call

+0

完美工作,謝謝。 –

+0

不客氣。 – gwiazdorrr

相關問題