类型推导给定成员函数指针与可变参数模板

时间:2013-10-15 17:27:55

标签: c++ templates c++11 variadic-templates decltype

假设我有一个成员函数指针,我怎么能编写自动推导出给定模板签名参数的代码:

 template<typename T> class Foo {};

 template<typename R, typename C, typename... A>
 class Foo<R(C, A...)> { };

对于C和R,没有任何问题,因为类似于此的技巧:

template<typename R, typename C, typename... A> 
R deduce_R_type(R(C::*)(A...));

template<typename R, typename C, typename... A>
C deduce_C_type(R(C::*)(A...));

然后我可以将其插入到Foo实例中,但是如何推导出来自模板的可变元部分的类型?

Foo<
decltype(deduce_R_type(&SomeClass::SomeFunction)) (
decltype(deduce_C_type(&SomeClass::SomeFunction)), ___ ??? ___)> instance

1 个答案:

答案 0 :(得分:7)

您至少需要一个帮助器,例如std::tuple

template<typename R, typename C, typename... A>
std::tuple<A...> deduce_A_tuple(R(C::*)(A...));

template<typename R, typename C, typename T>
struct FooHelper;

template<typename R, typename C, typename... A>
struct FooHelper< R, C, std::tuple<A...> >
{
    typedef Foo< R( C, A... ) > type;
};

然后你可以使用:

FooHelper< decltype(deduce_R_type(&SomeClass::SomeFunction)),
           decltype(deduce_C_type(&SomeClass::SomeFunction)), 
           decltype(deduce_A_tuple(&SomeClass::SomeFunction)) >::type instance;

Live example


正如用户DyP指出的那样,当你必须使用帮助时它可能会简单得多:

template<typename>
struct FooHelper;

template<typename R, typename C, typename... A>
struct FooHelper< R (C::*)(A...) >
{
    using type = Foo< R( C, A... ) >;
};

并将其用作

FooHelper< decltype(&SomeClass::SomeFunction) >::type instance;