Передача указателя на функцию-член с использованием переменных аргументов шаблона неоднозначна

Почему «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& но как ни странно это не помогает.
И нет, нет других функций-членов с таким же именем.

0

Решение

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; Вы должны переименовать их.

2

Другие решения


По вопросам рекламы [email protected]