2011-10-18 35 views
2

我們已經寫了大量的庫函數,其原型C++大多是這樣的:通用包裝器的功能,最後一個參數返回

void my_fun(
    const in_class & in_param_1, 
    const in_class & in_param_2, 
    const in_class & in_param_3, 
    out_class & out_param); 

是否有包裝這些功能,使下面就相當於一個通用的方法(假設out_param只寫到my_fun):

out_class my_out; 
my_fun(my_in1,my_in2,my_in3,my_out); 

out_class my_out = generic_wrapper(&my_fun,my_in1,my_in2,my_in3); 

如何寫一個這樣的generic_wrapper?如果這是可能的,那麼也可以寫入它,以便輸入參數的數量是可變的,所以我可以用my_fun2來說,它可能需要4個in_param_'s?

回答

3

考慮所有情況:

template<class T1, class Out> 
Out generic_wrapper(void (*f)(const T1 &, Out &), const T1 & t1) { 
    Out out; 
    f(t1,out); 
    return out; 
} 

template<class T1, class T2, class Out> 
Out generic_wrapper(void (*f)(const T1 &, const T2 &, Out &), const T1 & t1, const T1 & t2) { 
    Out out; 
    f(t1,t2,out); 
    return out; 
} 

// ..... 

template<class T1, class T2, class T3, class T4, class T5, class Out> 
Out generic_wrapper(void (*f)(const T1 &, const T2 &, const T3 &, const T4 &, const T5 &, Out &), const T1 & t1, const T1 & t2, const T3 & t3, const T4 & t4, const T5 & t5) { 
    Out out; 
    f(t1,t2,t3,t4,t5,out); 
    return out; 
} 
0

在C++ 0x中,我們也可以嘗試使用可變參數模板:

template <class Out, class... Ins> 
Out generic_wrapper(void (*fun)(const Ins&... , Out&), const Ins&... ins) 
{ 
    Out out; 
    fun(ins..., out); 
    return out; 
} 

,但我不能用它W/O明確speficying模板ARGS(GCC 4.6 .1):

int main() 
{ 
    in_class in; 
    out_class out1a = generic_wrapper(my_fun_1, in); // fails to compile... 
    out_class out1b = generic_wrapper<out_class, in_class>(my_fun_1, in); // works... 
    return 0; 
} 
1

使用C++ 11的可變參數模板,可以像這樣實現包裝:

template <class Func, class ...Args> 
typename last_argument_type<Func>::type wrapper(Func f, Args&& ...args) 
{ 
    typename last_argument_type<Func>::type result; 
    f(std::forward<Args>(args)..., result); 
    return result; 
} 

,我已經實現了last_argument_type爲:在http://ideone.com/ef3zD

//typedefs last type in T... as type 
template <class ...T> 
struct last_type; 

template <class T, class ...U> 
struct last_type<T, U...> { typedef typename last_type<U...>::type type; }; 

template <class T> 
struct last_type<T> { typedef T type; }; 

//typedefs the type of the last argument of a function as type 
//removes reference 
//e.g void(int, float, double&) -> type = double 
template <class ...Args> 
struct last_argument_type; 

template <class Ret, class ...Args> 
struct last_argument_type<Ret(*)(Args...)> { 
    typedef typename std::remove_reference<typename last_type<Args...>::type>::type type; 
}; 

完整的示例

相關問題