使用参数包推导函数参数类型

时间:2016-03-07 19:40:21

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

我试图使用指向成员函数指针和参数包的指针来调用函数。鉴于以下是代码:

class DemoClass {
public:
   void Printer(const DemoClass& sc, const int& i) {
   }
};



 template<typename R, typename T, typename ... Args/*, typename ... Params*/>
void MakeMemberActionDemoClass(R(T::*memberFunction)(Args...), Args&& ... args) 
{
}

int main()
{
    DemoClass d;
    int z;
    MakeMemberActionDemoClass(&DemoClass::Printer, d, z);
}

我收到以下错误:

error C2782: 'void MakeMemberActionDemoClass(R (__thiscall T::* )(Args...),Args &&...)' : template parameter 'Args' is ambiguous

1>          could be 'const DemoClass&, const int&'
1>          or       'DemoClass&, int&'

如果我删除&amp;&amp;在MakeMemberActionDemoClass的最后一个参数中,只有以下错误的区别如下:

1>          could be 'const DemoClass&, const int&'
1>          or       'DemoClass, int'

我应该怎样做才能正确推断参数类型?

提前致谢,

1 个答案:

答案 0 :(得分:2)

Args的两个实例都处于可推断的上下文中。它们必须生成相同的类型,否则编译器会抱怨它不明确。

一种方法是在一个或另一个上下文中阻止扣除。另一种方法是停止连接它们。

template<class T>struct tag_t{using type=T;};
template<class Tag>using type_t=typename Tag::type;

template<class T>using block_deduction=type_t<tag_t<T>>;

template<class R, class T, class...Args>
void MakeMemberActionDemoClass(
  R(T::*memberFunction)(Args...),
  block_deduction<Args>... args
) 
{
}

这可能需要两次复制值。

template<class R, class T, class...Args, class...Params>
auto MakeMemberActionDemoClass(
  R(T::*memberFunction)(Args...),
  Params&&... params
) 
->decltype( (std::declval<T*>()->*memberFunction)( std::declval<Params>()... ) )
{
}

将正确推断出它们,让您尽早向memberFunction和SFINAE完善,以检测过载失败。