简体   繁体   中英

cast helper for overloaded member function pointer

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

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!");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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