2013-03-07 96 views
1

所以問題很簡單,編譯器是否應該根據標準推斷出模板連接?演繹可變模板連接

例子:

template<typename... RUN_TIME, typename T, typename... CONSTRUCTION_TIME> 
Runnable<T, RUN_TIME...>* makeRunnable(T (*FunctionType)(CONSTRUCTION_TIME..., RUN_TIME...), CONSTRUCTION_TIME... ct_args) 
{ 
    ... 
} 

int print_function(char arg1, int arg2, const char* arg3); 

makeRunnable<const char*>(print_function, 'C', -3); 

應該編譯能夠推測該功能print_function是正常的傳遞,給出的參數和明確的模板?

查看更多; Previous Question

+1

我不能真正地讓你的問題的頭或尾,但是std :: bind有什麼問題? – 111111 2013-03-07 14:02:52

+0

沒有什麼,除了我試圖發展我自己的系統,並且我遇到了這個問題。 – Skeen 2013-03-07 14:06:35

+0

@Ali:你的意思是'吸收',因爲我也想爲我的操作系統內核做一個小的工作實現。 – Skeen 2013-03-07 14:40:43

回答

0

除了問題是什麼標準說什麼編譯器應該能夠做到,這裏的一些TMP,使其在編譯GCC:

/** PackDiff: 
* Template Metafunction to deduce the difference of two parameter packs. 
* To distinguish two packs we have to brace them in two tuples 
*/ 
template <class Tup1, class Tup2> struct PackDiff; 

/** Basic algorithm: (T, X1...) - (T, X2...) = (X1...) - (X2...) */ 
template <class T, class... Pack1, class... Pack2> 
struct PackDiff<std::tuple<T, Pack1...>, std::tuple<T, Pack2...>> 
    : PackDiff<std::tuple<Pack1...>, std::tuple<Pack2...>> {}; 

/** End of recursion: (X1...) -() = (X1...) */ 
template <class... Pack1> 
struct PackDiff<std::tuple<Pack1...>, std::tuple<>> 
{ 
    typedef std::tuple<Pack1...> type; 
}; 

/** Mismatch: (T, X1...) - (U, X2...) is undefined */ 
template <class T1, class... Pack1, class T2, class... Pack2> 
struct PackDiff<std::tuple<T1, Pack1...>, std::tuple<T2, Pack2...>> 
{ typedef struct PACK_MISMATCH {} type; }; 

/** Rest:() - (X2...) is undefined */ 
template <class... Pack2> 
struct PackDiff<std::tuple<>, std::tuple<Pack2...>> 
{ typedef struct LEFT_PACK_TOO_SHORT{} type; }; 



//make Runnable Type of T and a diff tuple: 
template <class T, class Tup1> struct MakeRunnableType; 

template <class T, class... Pack> 
struct MakeRunnableType<T, std::tuple<Pack...>> 
{ typedef Runnable<T, Pack...> type; }; 



template<typename... AllArgs, typename T, typename... SomeArgs> 
auto makeRunnable(T (*FunctionType)(AllArgs...), SomeArgs... ct_args) 
    -> typename MakeRunnableType<T, 
      typename PackDiff<std::tuple<AllArgs...>, 
       std::tuple<SomeArgs...> 
      >::type 
    >::type* 
{ 
    typedef typename PackDiff<std::tuple<AllArgs...>, 
       std::tuple<SomeArgs...> 
      >::type PackDiff_t; 
    typedef typename MakeRunnableType<T, PackDiff_t>::type ReturnType; 
    return new ReturnType(); 
} 

我知道。看起來不漂亮。但是works on GCC.

+0

您可以在makeRunnable函數中添加另一個可變參數模板,並讓函數指針將此作爲參數,這也使得它可以在gcc中編譯,但我想知道答案的問題是標準狀態關於可變模板連接。 – Skeen 2013-03-07 16:32:49

+0

有了第三個參數包,你必須指定它,因爲你只傳遞兩個參數給函數,所以編譯器只能推導出兩個參數包。至於標準問題,我會看看標準,也許我可以弄清楚什麼。 – 2013-03-08 07:57:08

+0

對! - 事實證明,這實際上是我在代碼中所做的,以避免這個問題。 – Skeen 2013-03-08 10:48:15