简体   繁体   English

可变参数模板指针,指向成员函数的声明/使用问题

[英]Variadic template pointer to member function declaration/usage issues

// 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);

Why doesn't the variadic template version work? 为什么可变参数模板版本不起作用? Am I missing some forwarding? 我错过一些转发吗?

I think this could serve as an example of what is happening in your code: 我认为这可以作为代码中发生的情况的一个示例:

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
}

The problem in line X is that you use &A::func and the compiler now needs to deduce the As... - which it can't. X行中的问题是您使用&A::func ,并且编译器现在需要推断出As...不能。 Line Y fixes that by explicitly casting it to the correct overload. Y行通过将其显式强制转换为正确的重载来解决此问题。

If you use the first version of test (the one commented out above), test 's signature contains the necessary type already (no deduction needed) and the compiler knows how to cast (in this case this means select ) the correct overload for func . 如果您使用test的第一个版本(上面已注释掉的那个),则test的签名已经包含了必需的类型(无需扣除),并且编译器知道如何为func (在这种情况下, 选择 )正确的重载。 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM