2013-03-07 98 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