Reputation: 537
I'm passing a method pointer to a function template. It works for some method pointers, but not others.
I tried to help the compiler to differentiate types (declared args vs. passed args) using the tricky my_type_identity (thank to Jarod42) but I fails too.
Here is that minimal code that exposes the problem:
template<class T> struct my_type_identity { using type = T ;};
struct Spam
{
};
struct Eggs
{
void f0 ( Spam ) {}
void f1 ( const Spam & ) {}
};
template <class C> struct Bread
{
C c ;
template <class F,class T> void apply1 ( void (F::*f)( T ), T t ) { (c.*f)(t) ; }
template <class F,class T> void apply2 ( void (F::*f)( T ), my_type_identity<T> t ) { (c.*f)(t) ; }
};
int main ()
{
Spam s ;
Bread<Eggs> b ;
b.apply1( &Eggs::f0,s ) ;
b.apply1( &Eggs::f1,s ) ; // error
b.apply2( &Eggs::f0,s ) ; // error
b.apply2( &Eggs::f1,s ) ; // error
}
Upvotes: 0
Views: 83
Reputation: 537
Finally a solution inspired by the one of suggested by JeJo seems to be good for me : It is compatible with c++11 and allows multiple parameters.
#include <iostream>
struct Spam
{
const char * foo () { return "mutable" ;}
const char * foo () const { return "const" ;}
};
struct Eggs
{
void f0() { std::cout << "f0()\n" ;}
void f1(Spam s) { std::cout << "f1(" << s.foo() << ")\n" ;}
void f2(Spam& s) { std::cout << "f2(" << s.foo() << ")\n" ;}
void f3(Spam* s) { std::cout << "f3(" << s->foo() << ")\n" ;}
void f4(const Spam* s) { std::cout << "f4(" << s->foo() << ")\n" ;}
void f5(const Spam& s) { std::cout << "f5(" << s.foo() << ")\n" ;}
void f6(const Spam& s , int x ) { std::cout << "f6(" << s.foo() << "," << x << ")\n" ;}
int f7(const Spam& s) { std::cout << "f7(" << s.foo() << ")\n" ; return 77 ;}
};
template <class C> struct Bread
{
C c;
template <class R=void,class F,class...P> R apply (F const&f,P&&...p)
{
return (c.*f)(p...) ;
}
};
int main()
{
Spam s;
Bread<Eggs> b;
b.apply(&Eggs::f0);
b.apply(&Eggs::f1,s);
b.apply(&Eggs::f2,s);
b.apply(&Eggs::f3,&s);
b.apply(&Eggs::f4,&s);
b.apply(&Eggs::f5,s);
b.apply(&Eggs::f6,s,88);
int x = b.apply<int>(&Eggs::f7,s) ;
std::cout << "f7 -> " << x << std::endl ;
}
Thanx you all!
Upvotes: 0
Reputation: 217398
In
template <class F,class T>
void apply ( void (F::*f)(T) , T t )
T
might be deduced from both parameters, and should be identical.
It is not your case.
You might change to
template <class F,class T>
void apply ( void (F::*f)(T) , std::type_identity_t<T> t )
to only deduce from first parameter.
Upvotes: 3