// This compiles and runs properly
using MemPtr = Entity&(OBFactory::*)(const Vec2i&, float);
void test(MemPtr mptr, const Vec2i& p, float d)
{
(getFactory().*mptr)(p, d);
}
// "no matching function for call to `test`,
// failed candidate template argument deduction"
template<typename... A> using MemPtr = Entity&(OBFactory::*)(A...);
template<typename... A> void test(MemPtr<A...> mptr, const Vec2i& p, float d)
{
(getFactory().*mptr)(p, d);
}
...
// I call both versions with
test(&OBFactory::func, Vec2i{0, 0}, 0.f);
为什么可变参数模板版本不起作用?我错过了一些转发吗?
答案 0 :(得分:1)
我认为这可以作为代码中发生的事情的一个例子:
struct A
{
// there are multiple overloads for func (or a template?)
void func(double) {}
void func(int) {}
};
//using MemPtr = void(A::*)(double);
//void test(MemPtr mptr, double d)
//{
// (A().*mptr)(d);
//}
template<typename... As> using MemPtr = void(A::*)(As...);
template<typename... As> void test(MemPtr<As...> mptr, double d)
{
(A().*mptr)(d);
}
int main()
{
// test(&A::func, 0.); // line X
test(static_cast<void(A::*)(double)>(&A::func), 0.); // line Y
}
X行中的问题是您使用&A::func
,编译器现在需要推导出As...
- 它不能。 Y行通过显式地将其强制转换为正确的重载来修复它。
如果您使用test
的第一个版本(上面注释掉的那个),test
的签名已经包含必要的类型(不需要推导),编译器知道如何投射(在这种情况意味着选择)func
的正确重载。