mardi 1 septembre 2015

Type mismatch when passing member function pointer to a function that takes MFP with variadic arguments

I have a template function that takes pointer to a member function of any type with any amount of arguments (but enforces some rules - it has to be void and the last argument has to be a pointer):

class Foo {
public:
    Foo() {}

    template<typename T, typename Out, typename ... In>
    void foo(T *obj, void(T::*func)(In ..., Out*)) {
        ...
    }
    ...
};

When I try to invoke the function, I get a type mismatch error:

class Bar {
public:
    Bar() {}
    void bar(int in, bool *out) {
        ...
    }
};

int main()
{
   Foo foo;
   Bar bar;

   foo.foo<Bar, bool, int>(&bar, &Bar::bar);
   ...
}

Error:

test.cpp: In function 'int main()':
test.cpp:41:44: error: no matching function to call to 'Foo::foo(Bar*, void (Bar::*)(int, bool*))'
    foo.foo<Bar, bool, int>(&bar, &Bar::bar);
                                           ^
test.cpp:24:10: note: candidate: template<class T, class Out, class ... In> void Foo::foo(T*, void (T::*)(In ..., Out*))
    void foo(T *obj, void(T::*func)(In ..., Out*))
         ^
test.cpp:24:10: note    template argument deduction/substitution failed:
test.cpp:41:44: note    mismatched types 'bool*' and 'int'
    foo.foo<Bar, bool, int>(&bar, &Bar::bar);
                                           ^

The interesting things is that when I make In a simple type instead of parameter pack then it compiles and works correctly. This seems to me like if the compiler did not expand the pack somewhere and try to match the second argument (bool*) to the first argument (int) instead of the second one.

Aucun commentaire:

Enregistrer un commentaire