Member function wrapper with one argument pattern?

I made a template function that takes a member function as a parameter.

However, since the class must be declared before it can be used as part of a member function parameter, I must make it a separate parameter:

template<typename C, void (C::*Method)(void)>
function<void(C*)> methodWrap()
{
}

This means that when I explicitly create an instance of the template (I want these wrappers to be generated at compile time, and not in the member pointer as an argument), I have to enter it twice when I use it:

function<void(C*)> someFunc = wrapMethod<SomeClass, &SomeClass::someMethod>();

Why can't I just write something like tis:

template<void (C::*Method)(void)>
function<void(C*)> methodWrap()
{
}

and let it capture type C and its pointer to a member function, without requiring you to enter SomeClass twice?

, C " ", ,

template<typename C>
template<void (C::*Method)(void)>
function<void(C*)> methodWrap()
{
}
+4
2

- , ,

#include <functional>

template<typename R, typename C, typename... Args>
struct MemberFunctionPointer
{
    typedef R Return;
    typedef C Class;
};

template<typename R, typename C>
constexpr auto inferMemberFunctionPointer(R (C::*method)())
{
    return MemberFunctionPointer<R,C>{};
}

template<typename T> 
constexpr auto methodWrap(T m)
{
    typedef typename decltype(inferMemberFunctionPointer(m))::Class Class;
    typedef typename decltype(inferMemberFunctionPointer(m))::Return Return;

        return std::function<Return (Class*)>();
}

struct B {};

struct A
{
    B f();   
};

void foo()
{
    auto const m = methodWrap( &A::f );
}

std::function constexpr, Wrap constexpr. , constexpr. static_assert, .

#include <functional>

template<typename R, typename C, typename... Args>
struct MemberFunctionPointer
{
    typedef R Return;
    typedef C Class;
};

template<typename R, typename C>
constexpr auto inferMemberFunctionPointer(R (C::*method)() const)
{
    return MemberFunctionPointer<R,C>{};
}

template<typename R, typename C>
struct MemberFunction
{
    constexpr explicit MemberFunction(R (C::*g)() const): f(g) {}

    constexpr R operator()(C const* obj) const
    {
        return (obj->*f)();
    }

    R (C::*f)() const;
};

template<typename T> 
constexpr auto methodWrap(T m)
{
    static_assert( std::is_member_function_pointer<T>::value, 
                   "Member function pointer expected!");

    typedef typename decltype(inferMemberFunctionPointer(m))::Class Class;
    typedef typename decltype(inferMemberFunctionPointer(m))::Return Return;

        return MemberFunction<Return, Class>{ MemberFunctionPointer<Return,Class>{} };
}

struct B {};

struct A
{
    constexpr B f() const;   
};

void foo()
{
    auto constexpr m = methodWrap( &A::f );
    auto constexpr a = A{};
    m( &a );

    auto b = A{};
    m( &b );
}
+2

- :

template<void (C::*Method)(void)>
function<void(C*)> methodWrap()

C. , typename C.

, C " ", ,

, . .

- :

 template<typename C>
 std::function<void(C&)> wrap(void(C::*mf)())
 {
   return std::function<void(C&)>(mf);
 }

: wrap(&Obj::memfun);

, , , .

0

Source: https://habr.com/ru/post/1620446/


All Articles