Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can the callable returned from std::mem_fn be used on objects and on shared_ptrs?

Tags:

c++

c++11

c++14

The following code works, but I do not understand why it does.

#include <functional>
#include <iostream>
#include <memory>

struct foo
{
    int get_val() const
    {
        return 42;
    }
};

int main()
{
    foo obj;
    std::shared_ptr<foo> ptr = std::make_shared<foo>();

    const auto getter = std::mem_fn( &foo::get_val );

    std::cout << getter( obj ) << std::endl;
    std::cout << getter( ptr ) << std::endl;
}

Why can getter be used on obj and on ptr? I expected it to only work on obj.

like image 970
Tobias Hermann Avatar asked Nov 26 '25 14:11

Tobias Hermann


1 Answers

From the std::mem_fn cppreference page:

Function template std::mem_fn generates wrapper objects for pointers to members, which can store, copy, and invoke a pointer to member. Both references and pointers (including smart pointers) to an object can be used when invoking a std::mem_fn.

Short answer: because the standard says so.

I guess that it just a more convenient and general interface, as you can, for example, write a single template function that calls a std::mem_fn which will work with both references and pointers:

const auto getter = std::mem_fn( &foo::get_val );

template <typename T>
void call_getter(T&& x)
{
    // do something
    getter(x);
    // do something
}

int main()
{
    foo obj;
    std::shared_ptr<foo> ptr = std::make_shared<foo>();

    call_getter( obj );
    call_getter( ptr );
}

In the above example you only need one overload of call_getter.

like image 108
Vittorio Romeo Avatar answered Nov 28 '25 04:11

Vittorio Romeo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!