C++ 可变模板拼接的推导

C++ 可变模板拼接的推导,c++,c++11,standards,variadic-templates,template-argument-deduction,C++,C++11,Standards,Variadic Templates,Template Argument Deduction,所以问题很简单,编译器是否应该能够根据标准推断模板连接 例如: template<typename... RUN_TIME, typename T, typename... CONSTRUCTION_TIME> Runnable<T, RUN_TIME...>* makeRunnable(T (*FunctionType)(CONSTRUCTION_TIME..., RUN_TIME...), CONSTRUCTION_TIME... ct_args) { ..

所以问题很简单,编译器是否应该能够根据标准推断模板连接

例如:

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);
模板
Runnable*MakerRunnable(T(*函数类型)(构造时间…,运行时间…,构造时间…ct参数)
{
...
}
int print_函数(字符arg1、int arg2、常量字符*arg3);
makeRunnable(打印函数'C',-3);
在给定参数和显式模板的情况下,编译器是否应该能够判断函数
print\u函数
是否可以通过


多看

除了标准中关于编译器应该能够做什么的问题之外,这里有一些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();
}
/**PackDiff:
*模板元函数来推断两个参数包的差异。
*为了区分两个包,我们必须将它们分成两个元组
*/
模板结构PackDiff;
/**基本算法:(T,X1…-(T,X2…=(X1…-(X2…)*/
样板
结构PackDiff
:PackDiff{};
/**递归结束:(X1…-()=(X1…)*/
样板
结构PackDiff
{
typedef std::元组类型;
};
/**不匹配:(T,X1…-(U,X2…)未定义*/
样板
结构PackDiff
{typedef结构包_不匹配{}type;};
/**Rest:()-(X2…)未定义*/
样板
结构PackDiff
{typedef struct LEFT_PACK_TOO_SHORT{}type;};
//将T和差异元组设为可运行类型:
模板结构MakeRunnableType;
样板
结构MakerRunnableType
{typedef Runnable type;};
样板
自动生成可运行(T(*函数类型)(AllArgs…,SomeArgs…,ct_args)

->typename MakerunnableType我不能完全理解你的问题,但是std::bind有什么问题吗?什么都没有,只是我在尝试开发自己的系统,我遇到了这个问题。@Ali:你说的“吸收”是什么意思,因为我还想为我的操作系统内核提供一个小的工作实现。你为什么(尝试)这样做误导编译器?你传递了一个
int(*)(char,int,char const*)
,但是定义
T
char const*
-编译器不会为你推断,因为你传递的函数poitner不适合可能的签名。@Skeen我认为这是编译器开始推断类型的一部分。如果从右边开始,它可以推断出
构造时间…
。如果它从左边开始,它必须以某种方式匹配到一个函数签名,然后失败。然而,这是一个有点学术性的问题,因为无论哪种编译器是正确的,您尝试做的都明显缺乏可移植性。您只需向makeRunnable函数添加另一个可变模板,并让函数指针将其作为参数,这使得.it也可以在gcc中编译,但我想知道答案的问题是,关于可变模板串联的标准说明是什么。对于第三个参数包,您必须指定它,因为您只将两个参数传递给函数,因此编译器只能推断出两个参数。至于标准问题,我来看看标准,也许我能想出一些办法。对事实证明,为了避免这个问题,我在代码中也做了同样的事情。