Reputation: 25663
I want to have a "nicer" cast operation for a pointer to method.
Given is a class with overloaded member functions and a template which eats every kind of member pointers and objects and simply call them.
class A
{
public:
void Do( int i ) { std::cout << "Hallo with int " << i << std::endl;}
void Do( float f ) { std::cout << "and with float " << f << std::endl;}
void Do( std::string s ) { std::cout << "also with string " << s << std::endl;}
};
template <typename OBJECT, typename METHOD, typename ... PARMS>
void Call( OBJECT& obj, METHOD m, PARMS ... parms)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
(obj.*m)(parms...);
}
Now, if I want to use the Call
template, I have to manually cast the pointer to get the correct version of overloaded functions like:
Call( a, static_cast< void(A::*)(int)>( &A::Do ), 1);
Call( a, static_cast< void(A::*)(float)>( &A::Do ), 8.88);
Call( a, static_cast< void(A::*)(std::string)>( &A::Do ), "Willi");
So I like to make the cast a bit easier to read and got this helper class:
template <typename > class Cast;
template < typename RET, typename ... ARGS >
class Cast< RET(ARGS...)>
{
public:
template < typename OBJ >
static auto From( RET(OBJ::*ptr)(ARGS...))-> RET(OBJ::*)(ARGS...)
{
return ptr;
}
};
and can use it as:
Call( a, Cast<void(int)>::From( &A::Do ), 100);
Call( a, Cast<void(float)>::From( &A::Do ), 4.46);
Call( a, Cast<void(std::string)>::From( &A::Do ),"Check it");
Q:
Is it possible to make my class Cast
a template function to get the syntax for the cast call a bit easier? I want something which can be called like this:
Call( a, Cast<void(std::string)>( &A::Do ), "Yeeeaaa!");
But I can't find a way to write a template function this way because any kind of specialisation I wrote was not allowed.
Any kind of c++ is allowed. If C++17 gives a new way, let me know!
Why I can't use the parameters for a lambda inside the call function:
My real code needs only to register the pointers but do not call the pointers direct. So the cast function must also work with:
Register( a, Cast<void(int)>::From( &A::Do ));
Upvotes: 1
Views: 386
Reputation: 13589
You don't have to separate out arguments and result type only to join them again. Just declare a member pointer to the function type:
template <typename F, typename C>
auto Cast(F (C::*ptr)) {
return ptr;
}
Your desired syntax works:
Call(a, Cast<void(std::string)>(&A::Do), "Yeeeaaa!");
Upvotes: 2