使用可变参数模板参数传递成员函数指针是不明确的

时间:2015-02-17 23:13:33

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

为什么“TArgs”在我的例子中含糊不清?

编译器应该知道唯一存在的函数签名

virtual CGame::NetCreatePlayer(CNetPeer* _pPeer, int _ObjectID, const CNetMessage& _ObjectData, bool _bAuthority); 

并在此函数中推导出正确的TArgs

template<typename... TArgs >
void INetInterface<TSubClass>::NetCall(void(TSubClass::*_pFunc)(CNetPeer*, TArgs...), CNetPeer* _pPeer, TArgs... _Params);

我想这样称呼它:

CNetMessage obj;
//...
NetCall(&CGame_Server::NetCreatePlayer, _pClient, 0, obj, true);

CGame_Server继承了CGame。

编译器输出:

4> error C2782: 'void INetInterface<CGame>::NetCall(void (__thiscall CGame::* )(CNetPeer *,TArgs...),CNetPeer *,TArgs...)' : template parameter 'TArgs' is ambiguous 4> NetInterface.h(82) : see declaration of INetInterface<CGame>::NetCall' 4> could be 'int, const CNetMessage&, bool' 4> or 'int, CNetMessage, bool'

它不能是'int,CNetMessage,bool',对吧?

有没有办法解决这个问题? 我试着施展到const CNetMessage&,但奇怪的是,这没有帮助。 并且没有其他成员函数具有相同的名称。

1 个答案:

答案 0 :(得分:2)

NetCall(&CGame_Server::NetCreatePlayer, _pClient, 0, obj, true);

此通话中有两个位置可以推断出TArgs

  • 从成员函数指针的类型中,编译器推导出TArgs == int, const CNetMessage&, bool
  • 从参数0, obj, true开始,编译器推导出TArgs == int, CNetMessage, bool

结果冲突。要解决此问题,请使用identity技巧将第二个TArgs放入非推断的上下文中:

template<class T> struct identity { using type = T; };    
template<class T> using identity_t = typename identity<T>::type;

template<typename... TArgs >
void INetInterface<TSubClass>::NetCall(void(TSubClass::*_pFunc)(CNetPeer*, TArgs...),
                                       CNetPeer* _pPeer, identity_t<TArgs>... params);

作为旁注,_Params是保留的标识符,以及_ObjectData_ObjectID;你应该重命名它们。