Pass a member function as Compare operator for C++ standard library algorithm












0















In my code I have now something like



    Foo bar;
std::unordered_set<Foo>::iterator minElement =
std::min_element(std::begin(mySet),
std::end(mySet),
[&bar](Foo const &lhs, Foo const &rhs) {
return bar.myWeakLessOperator(lhs, rhs);
});


I wonder wether it exists a way to simplify it by passing directly the member function myWeakLessOperator (that is not static) instead of writing a lambda function just to make to call.



I would like to obtain something like



    Foo bar;
std::unordered_set<Foo>::iterator minElement =
std::min_element(std::begin(mySet),
std::end(mySet),
/* something that rely to */ bar.myWeakLessOperator);


Any idea if it possible and how to do it ?










share|improve this question

























  • with std::bind(&Foo::myWeakLessOperator, std::placeholders::_1, std::placeholders::_1, std::placeholders::_2) you can get away with bar, but why not just make a static version ?

    – Piotr Skotnicki
    Nov 15 '18 at 17:56











  • @PiotrSkotnicki in that case OP may just remove the first parameter from myWeakLessOperator altogether since it's just this duplicated.

    – Pezo
    Nov 15 '18 at 17:58






  • 1





    @Azias could you elaborate on what myWeakLessOperator does, why is it a member function when it seems to compare two unrelated objects?

    – Pezo
    Nov 15 '18 at 18:00











  • I cannot have a static version because the result of myWeakLessOperator will depend on the object. Actually my operator compares two objects against their distance to a main object (myWeakLessOperator could be renamed ClosestThan). baris the main object, and my final goal with std::min_element is to find the element from mySet' that is the closest to bar`

    – Azias
    Nov 15 '18 at 18:15













  • Then my answer is not a solution unfortunately, what you want is basically a bound member function. I had a need for this a couple days ago, but couldn't find anything, so I wrote my own. I'm trying to recreate it just now.

    – Pezo
    Nov 15 '18 at 18:21


















0















In my code I have now something like



    Foo bar;
std::unordered_set<Foo>::iterator minElement =
std::min_element(std::begin(mySet),
std::end(mySet),
[&bar](Foo const &lhs, Foo const &rhs) {
return bar.myWeakLessOperator(lhs, rhs);
});


I wonder wether it exists a way to simplify it by passing directly the member function myWeakLessOperator (that is not static) instead of writing a lambda function just to make to call.



I would like to obtain something like



    Foo bar;
std::unordered_set<Foo>::iterator minElement =
std::min_element(std::begin(mySet),
std::end(mySet),
/* something that rely to */ bar.myWeakLessOperator);


Any idea if it possible and how to do it ?










share|improve this question

























  • with std::bind(&Foo::myWeakLessOperator, std::placeholders::_1, std::placeholders::_1, std::placeholders::_2) you can get away with bar, but why not just make a static version ?

    – Piotr Skotnicki
    Nov 15 '18 at 17:56











  • @PiotrSkotnicki in that case OP may just remove the first parameter from myWeakLessOperator altogether since it's just this duplicated.

    – Pezo
    Nov 15 '18 at 17:58






  • 1





    @Azias could you elaborate on what myWeakLessOperator does, why is it a member function when it seems to compare two unrelated objects?

    – Pezo
    Nov 15 '18 at 18:00











  • I cannot have a static version because the result of myWeakLessOperator will depend on the object. Actually my operator compares two objects against their distance to a main object (myWeakLessOperator could be renamed ClosestThan). baris the main object, and my final goal with std::min_element is to find the element from mySet' that is the closest to bar`

    – Azias
    Nov 15 '18 at 18:15













  • Then my answer is not a solution unfortunately, what you want is basically a bound member function. I had a need for this a couple days ago, but couldn't find anything, so I wrote my own. I'm trying to recreate it just now.

    – Pezo
    Nov 15 '18 at 18:21
















0












0








0








In my code I have now something like



    Foo bar;
std::unordered_set<Foo>::iterator minElement =
std::min_element(std::begin(mySet),
std::end(mySet),
[&bar](Foo const &lhs, Foo const &rhs) {
return bar.myWeakLessOperator(lhs, rhs);
});


I wonder wether it exists a way to simplify it by passing directly the member function myWeakLessOperator (that is not static) instead of writing a lambda function just to make to call.



I would like to obtain something like



    Foo bar;
std::unordered_set<Foo>::iterator minElement =
std::min_element(std::begin(mySet),
std::end(mySet),
/* something that rely to */ bar.myWeakLessOperator);


Any idea if it possible and how to do it ?










share|improve this question
















In my code I have now something like



    Foo bar;
std::unordered_set<Foo>::iterator minElement =
std::min_element(std::begin(mySet),
std::end(mySet),
[&bar](Foo const &lhs, Foo const &rhs) {
return bar.myWeakLessOperator(lhs, rhs);
});


I wonder wether it exists a way to simplify it by passing directly the member function myWeakLessOperator (that is not static) instead of writing a lambda function just to make to call.



I would like to obtain something like



    Foo bar;
std::unordered_set<Foo>::iterator minElement =
std::min_element(std::begin(mySet),
std::end(mySet),
/* something that rely to */ bar.myWeakLessOperator);


Any idea if it possible and how to do it ?







c++ c++11 standard-library






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 15 '18 at 18:16









HolyBlackCat

16.8k33468




16.8k33468










asked Nov 15 '18 at 17:45









AziasAzias

11418




11418













  • with std::bind(&Foo::myWeakLessOperator, std::placeholders::_1, std::placeholders::_1, std::placeholders::_2) you can get away with bar, but why not just make a static version ?

    – Piotr Skotnicki
    Nov 15 '18 at 17:56











  • @PiotrSkotnicki in that case OP may just remove the first parameter from myWeakLessOperator altogether since it's just this duplicated.

    – Pezo
    Nov 15 '18 at 17:58






  • 1





    @Azias could you elaborate on what myWeakLessOperator does, why is it a member function when it seems to compare two unrelated objects?

    – Pezo
    Nov 15 '18 at 18:00











  • I cannot have a static version because the result of myWeakLessOperator will depend on the object. Actually my operator compares two objects against their distance to a main object (myWeakLessOperator could be renamed ClosestThan). baris the main object, and my final goal with std::min_element is to find the element from mySet' that is the closest to bar`

    – Azias
    Nov 15 '18 at 18:15













  • Then my answer is not a solution unfortunately, what you want is basically a bound member function. I had a need for this a couple days ago, but couldn't find anything, so I wrote my own. I'm trying to recreate it just now.

    – Pezo
    Nov 15 '18 at 18:21





















  • with std::bind(&Foo::myWeakLessOperator, std::placeholders::_1, std::placeholders::_1, std::placeholders::_2) you can get away with bar, but why not just make a static version ?

    – Piotr Skotnicki
    Nov 15 '18 at 17:56











  • @PiotrSkotnicki in that case OP may just remove the first parameter from myWeakLessOperator altogether since it's just this duplicated.

    – Pezo
    Nov 15 '18 at 17:58






  • 1





    @Azias could you elaborate on what myWeakLessOperator does, why is it a member function when it seems to compare two unrelated objects?

    – Pezo
    Nov 15 '18 at 18:00











  • I cannot have a static version because the result of myWeakLessOperator will depend on the object. Actually my operator compares two objects against their distance to a main object (myWeakLessOperator could be renamed ClosestThan). baris the main object, and my final goal with std::min_element is to find the element from mySet' that is the closest to bar`

    – Azias
    Nov 15 '18 at 18:15













  • Then my answer is not a solution unfortunately, what you want is basically a bound member function. I had a need for this a couple days ago, but couldn't find anything, so I wrote my own. I'm trying to recreate it just now.

    – Pezo
    Nov 15 '18 at 18:21



















with std::bind(&Foo::myWeakLessOperator, std::placeholders::_1, std::placeholders::_1, std::placeholders::_2) you can get away with bar, but why not just make a static version ?

– Piotr Skotnicki
Nov 15 '18 at 17:56





with std::bind(&Foo::myWeakLessOperator, std::placeholders::_1, std::placeholders::_1, std::placeholders::_2) you can get away with bar, but why not just make a static version ?

– Piotr Skotnicki
Nov 15 '18 at 17:56













@PiotrSkotnicki in that case OP may just remove the first parameter from myWeakLessOperator altogether since it's just this duplicated.

– Pezo
Nov 15 '18 at 17:58





@PiotrSkotnicki in that case OP may just remove the first parameter from myWeakLessOperator altogether since it's just this duplicated.

– Pezo
Nov 15 '18 at 17:58




1




1





@Azias could you elaborate on what myWeakLessOperator does, why is it a member function when it seems to compare two unrelated objects?

– Pezo
Nov 15 '18 at 18:00





@Azias could you elaborate on what myWeakLessOperator does, why is it a member function when it seems to compare two unrelated objects?

– Pezo
Nov 15 '18 at 18:00













I cannot have a static version because the result of myWeakLessOperator will depend on the object. Actually my operator compares two objects against their distance to a main object (myWeakLessOperator could be renamed ClosestThan). baris the main object, and my final goal with std::min_element is to find the element from mySet' that is the closest to bar`

– Azias
Nov 15 '18 at 18:15







I cannot have a static version because the result of myWeakLessOperator will depend on the object. Actually my operator compares two objects against their distance to a main object (myWeakLessOperator could be renamed ClosestThan). baris the main object, and my final goal with std::min_element is to find the element from mySet' that is the closest to bar`

– Azias
Nov 15 '18 at 18:15















Then my answer is not a solution unfortunately, what you want is basically a bound member function. I had a need for this a couple days ago, but couldn't find anything, so I wrote my own. I'm trying to recreate it just now.

– Pezo
Nov 15 '18 at 18:21







Then my answer is not a solution unfortunately, what you want is basically a bound member function. I had a need for this a couple days ago, but couldn't find anything, so I wrote my own. I'm trying to recreate it just now.

– Pezo
Nov 15 '18 at 18:21














4 Answers
4






active

oldest

votes


















2














A possible solution is to use a struct that satisfies Compare inside Foo:



class Foo 
{
public:
struct WeakLessOperator
{
bool operator()(const Foo& a, const Foo& b)
{
// implementation - take care of meeting requirements of Compare
return true;
}
};
WeakLessOperator myWeakLessOperator;
};

Foo bar;

auto minElement =
std::min_element(std::begin(mySet),
std::end(mySet),
bar.myWeakLessOperator);





share|improve this answer

































    2














    So you want to have a function object that represents a member function bound to a particular receiver. Unfortunately, there's nothing I could find in the standard or Boost that does that.



    What you can do is write your own fairly easily.



    template <typename R, typename T>
    struct member_function_binder {
    T *receiver;
    R T::*pmf;

    template <typename... Args>
    auto operator()(Args&&... args) {
    return (receiver->*pmf)(std::forward<Args>(args)...);
    }
    };

    template <typename R, typename T>
    auto bind_member_function(R T::*pmf, T &receiver) {
    return member_function_binder<R, T>{&receiver, pmf};
    }


    Have a look at the live demo, I think this might be what you want.





    Even more concise, you don't need to have a separate class member_function_binder if you return a lambda from bind_member_function like so:



    template <typename R, typename T>
    auto bind_member_function(R T::*pmf, T &receiver) {
    return [pmf, &receiver](auto&&... args) {
    return (receiver.*pmf)(std::forward<decltype(args)>(args)...);
    };
    }


    Live demo





    Solution to pass a unary member function like Foo::compareTo(const Foo &rhs), not what OP asked:



    What you want is std::mem_fn; it's a wrapper that makes a member function pointer into a function object. You would use it like this:



    auto min = std::min_element(
    begin(mySet), end(mySet), std::mem_fn(&Foo::myWeakLessOperator));





    share|improve this answer


























    • myWeakLessOperator is a 2-parameter member function

      – Piotr Skotnicki
      Nov 15 '18 at 17:55











    • @PiotrSkotnicki I just noticed that too, that doesn't seem very sensible though.

      – Pezo
      Nov 15 '18 at 17:56











    • I don't think this would work, as you need 3 parameters to invoke the wrapper properly in this example.

      – user1095108
      Nov 15 '18 at 17:56



















    1














    you can use std::bind, or some other wrapper.



    EXAMPLE:



    using namespace std::placeholders;
    Foo bar;
    std::unordered_set<Foo>::iterator minElement =
    std::min_element(std::begin(mySet),
    std::end(mySet),
    std::bind(&Foo::myWeakLessOperator, bar, _1, _2));


    OR



    Foo bar;
    std::unordered_set<Foo>::iterator minElement =
    std::min_element(std::begin(mySet),
    std::end(mySet),
    gnr::memfun<MEMFUN(Foo::myWeakLessOperator)>(bar));





    share|improve this answer


























    • Can you give an example, I am not used to std::bind and co, I cannot see how to use it.

      – Azias
      Nov 15 '18 at 18:30











    • Lambda is superior to everything, though, faster, takes up less space, ...

      – user1095108
      Nov 15 '18 at 18:53











    • I have tried with this example and it effectively does the job. thanks.

      – Azias
      Nov 16 '18 at 8:01











    • You should know that std::bind is a lambda precursor. Effectively, the lambda replaces it and is superior.

      – user1095108
      Nov 16 '18 at 12:24



















    0














    The closest to what you want is maybe



    auto minElement =
    std::min_element(
    std::begin(mySet),
    std::end(mySet),
    mem_fun_functor(&Foo::myWeakLessOperator)
    );


    There is std::mem_fun (deprecated in c++11) and std::mem_fn both wrap a member function pointer, though both take a instance as parameter to invoke the member function. If you want a functor that wraps the object also, i think you need to write your own:



    auto mem_fun_functor = 
    [&bar](decltype(&Foo::myWeakLessOperator) f){
    return [f,&bar](const Foo& a,const Foo& b) {
    return (bar.*f)(a,b);
    };
    };


    However, given that none of the answers is really much shorter or leading to cleaner code, I would consider to just use your first version with the lambda (unless you maybe have many different member functions that you want to use as comparator).



    What do you actually mean by "simplifying" ? You do need to specify the object you want to call the member function on, you need to specify how you want to forward the parameters. Thats basically all the lambda does.



    Defering all this to a functor as for example above makes your code more complicated rather than simpler. In your first snippet anybody familiar with standard algorithms can look at that few lines of code and fully understand what is going on.



    Eventually it is a matter of style, and what you consider as readable, but being able to declare stuff in the most narrowest scope is one big advantage of using lambdas.






    share|improve this answer


























    • Correction: std::mem_fun was deprecated long ago and removed in C++17, you shouldn't use that. std::mem_fn is the way to go, it takes both references and pointers (raw or smart) as receivers.

      – Pezo
      Nov 15 '18 at 20:51











    • @Pezo thanks, corrected

      – user463035818
      Nov 15 '18 at 20:54











    • I really like your idea of returning a lambda, I never think of that.

      – Pezo
      Nov 15 '18 at 20:56











    • @Pezo my favourite is mjdmochowski's answer, though I really think just writing the lambda directly in the algorithm call is the most clean way. Its a bit of typing, but I prever to have everything in the most narrow scope. Whether there are reasons to pull something to a higher scope isnt really clear from the question

      – user463035818
      Nov 15 '18 at 21:00













    • I don't particularly like that solution since it'll waste space, because you need a reference/pointer to the containing object in the operator object (so it can access members).

      – Pezo
      Nov 16 '18 at 11:05











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53325193%2fpass-a-member-function-as-compare-operator-for-c-standard-library-algorithm%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    A possible solution is to use a struct that satisfies Compare inside Foo:



    class Foo 
    {
    public:
    struct WeakLessOperator
    {
    bool operator()(const Foo& a, const Foo& b)
    {
    // implementation - take care of meeting requirements of Compare
    return true;
    }
    };
    WeakLessOperator myWeakLessOperator;
    };

    Foo bar;

    auto minElement =
    std::min_element(std::begin(mySet),
    std::end(mySet),
    bar.myWeakLessOperator);





    share|improve this answer






























      2














      A possible solution is to use a struct that satisfies Compare inside Foo:



      class Foo 
      {
      public:
      struct WeakLessOperator
      {
      bool operator()(const Foo& a, const Foo& b)
      {
      // implementation - take care of meeting requirements of Compare
      return true;
      }
      };
      WeakLessOperator myWeakLessOperator;
      };

      Foo bar;

      auto minElement =
      std::min_element(std::begin(mySet),
      std::end(mySet),
      bar.myWeakLessOperator);





      share|improve this answer




























        2












        2








        2







        A possible solution is to use a struct that satisfies Compare inside Foo:



        class Foo 
        {
        public:
        struct WeakLessOperator
        {
        bool operator()(const Foo& a, const Foo& b)
        {
        // implementation - take care of meeting requirements of Compare
        return true;
        }
        };
        WeakLessOperator myWeakLessOperator;
        };

        Foo bar;

        auto minElement =
        std::min_element(std::begin(mySet),
        std::end(mySet),
        bar.myWeakLessOperator);





        share|improve this answer















        A possible solution is to use a struct that satisfies Compare inside Foo:



        class Foo 
        {
        public:
        struct WeakLessOperator
        {
        bool operator()(const Foo& a, const Foo& b)
        {
        // implementation - take care of meeting requirements of Compare
        return true;
        }
        };
        WeakLessOperator myWeakLessOperator;
        };

        Foo bar;

        auto minElement =
        std::min_element(std::begin(mySet),
        std::end(mySet),
        bar.myWeakLessOperator);






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 15 '18 at 18:14

























        answered Nov 15 '18 at 18:06









        mjdmochowskimjdmochowski

        213




        213

























            2














            So you want to have a function object that represents a member function bound to a particular receiver. Unfortunately, there's nothing I could find in the standard or Boost that does that.



            What you can do is write your own fairly easily.



            template <typename R, typename T>
            struct member_function_binder {
            T *receiver;
            R T::*pmf;

            template <typename... Args>
            auto operator()(Args&&... args) {
            return (receiver->*pmf)(std::forward<Args>(args)...);
            }
            };

            template <typename R, typename T>
            auto bind_member_function(R T::*pmf, T &receiver) {
            return member_function_binder<R, T>{&receiver, pmf};
            }


            Have a look at the live demo, I think this might be what you want.





            Even more concise, you don't need to have a separate class member_function_binder if you return a lambda from bind_member_function like so:



            template <typename R, typename T>
            auto bind_member_function(R T::*pmf, T &receiver) {
            return [pmf, &receiver](auto&&... args) {
            return (receiver.*pmf)(std::forward<decltype(args)>(args)...);
            };
            }


            Live demo





            Solution to pass a unary member function like Foo::compareTo(const Foo &rhs), not what OP asked:



            What you want is std::mem_fn; it's a wrapper that makes a member function pointer into a function object. You would use it like this:



            auto min = std::min_element(
            begin(mySet), end(mySet), std::mem_fn(&Foo::myWeakLessOperator));





            share|improve this answer


























            • myWeakLessOperator is a 2-parameter member function

              – Piotr Skotnicki
              Nov 15 '18 at 17:55











            • @PiotrSkotnicki I just noticed that too, that doesn't seem very sensible though.

              – Pezo
              Nov 15 '18 at 17:56











            • I don't think this would work, as you need 3 parameters to invoke the wrapper properly in this example.

              – user1095108
              Nov 15 '18 at 17:56
















            2














            So you want to have a function object that represents a member function bound to a particular receiver. Unfortunately, there's nothing I could find in the standard or Boost that does that.



            What you can do is write your own fairly easily.



            template <typename R, typename T>
            struct member_function_binder {
            T *receiver;
            R T::*pmf;

            template <typename... Args>
            auto operator()(Args&&... args) {
            return (receiver->*pmf)(std::forward<Args>(args)...);
            }
            };

            template <typename R, typename T>
            auto bind_member_function(R T::*pmf, T &receiver) {
            return member_function_binder<R, T>{&receiver, pmf};
            }


            Have a look at the live demo, I think this might be what you want.





            Even more concise, you don't need to have a separate class member_function_binder if you return a lambda from bind_member_function like so:



            template <typename R, typename T>
            auto bind_member_function(R T::*pmf, T &receiver) {
            return [pmf, &receiver](auto&&... args) {
            return (receiver.*pmf)(std::forward<decltype(args)>(args)...);
            };
            }


            Live demo





            Solution to pass a unary member function like Foo::compareTo(const Foo &rhs), not what OP asked:



            What you want is std::mem_fn; it's a wrapper that makes a member function pointer into a function object. You would use it like this:



            auto min = std::min_element(
            begin(mySet), end(mySet), std::mem_fn(&Foo::myWeakLessOperator));





            share|improve this answer


























            • myWeakLessOperator is a 2-parameter member function

              – Piotr Skotnicki
              Nov 15 '18 at 17:55











            • @PiotrSkotnicki I just noticed that too, that doesn't seem very sensible though.

              – Pezo
              Nov 15 '18 at 17:56











            • I don't think this would work, as you need 3 parameters to invoke the wrapper properly in this example.

              – user1095108
              Nov 15 '18 at 17:56














            2












            2








            2







            So you want to have a function object that represents a member function bound to a particular receiver. Unfortunately, there's nothing I could find in the standard or Boost that does that.



            What you can do is write your own fairly easily.



            template <typename R, typename T>
            struct member_function_binder {
            T *receiver;
            R T::*pmf;

            template <typename... Args>
            auto operator()(Args&&... args) {
            return (receiver->*pmf)(std::forward<Args>(args)...);
            }
            };

            template <typename R, typename T>
            auto bind_member_function(R T::*pmf, T &receiver) {
            return member_function_binder<R, T>{&receiver, pmf};
            }


            Have a look at the live demo, I think this might be what you want.





            Even more concise, you don't need to have a separate class member_function_binder if you return a lambda from bind_member_function like so:



            template <typename R, typename T>
            auto bind_member_function(R T::*pmf, T &receiver) {
            return [pmf, &receiver](auto&&... args) {
            return (receiver.*pmf)(std::forward<decltype(args)>(args)...);
            };
            }


            Live demo





            Solution to pass a unary member function like Foo::compareTo(const Foo &rhs), not what OP asked:



            What you want is std::mem_fn; it's a wrapper that makes a member function pointer into a function object. You would use it like this:



            auto min = std::min_element(
            begin(mySet), end(mySet), std::mem_fn(&Foo::myWeakLessOperator));





            share|improve this answer















            So you want to have a function object that represents a member function bound to a particular receiver. Unfortunately, there's nothing I could find in the standard or Boost that does that.



            What you can do is write your own fairly easily.



            template <typename R, typename T>
            struct member_function_binder {
            T *receiver;
            R T::*pmf;

            template <typename... Args>
            auto operator()(Args&&... args) {
            return (receiver->*pmf)(std::forward<Args>(args)...);
            }
            };

            template <typename R, typename T>
            auto bind_member_function(R T::*pmf, T &receiver) {
            return member_function_binder<R, T>{&receiver, pmf};
            }


            Have a look at the live demo, I think this might be what you want.





            Even more concise, you don't need to have a separate class member_function_binder if you return a lambda from bind_member_function like so:



            template <typename R, typename T>
            auto bind_member_function(R T::*pmf, T &receiver) {
            return [pmf, &receiver](auto&&... args) {
            return (receiver.*pmf)(std::forward<decltype(args)>(args)...);
            };
            }


            Live demo





            Solution to pass a unary member function like Foo::compareTo(const Foo &rhs), not what OP asked:



            What you want is std::mem_fn; it's a wrapper that makes a member function pointer into a function object. You would use it like this:



            auto min = std::min_element(
            begin(mySet), end(mySet), std::mem_fn(&Foo::myWeakLessOperator));






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 16 '18 at 11:03

























            answered Nov 15 '18 at 17:52









            PezoPezo

            970512




            970512













            • myWeakLessOperator is a 2-parameter member function

              – Piotr Skotnicki
              Nov 15 '18 at 17:55











            • @PiotrSkotnicki I just noticed that too, that doesn't seem very sensible though.

              – Pezo
              Nov 15 '18 at 17:56











            • I don't think this would work, as you need 3 parameters to invoke the wrapper properly in this example.

              – user1095108
              Nov 15 '18 at 17:56



















            • myWeakLessOperator is a 2-parameter member function

              – Piotr Skotnicki
              Nov 15 '18 at 17:55











            • @PiotrSkotnicki I just noticed that too, that doesn't seem very sensible though.

              – Pezo
              Nov 15 '18 at 17:56











            • I don't think this would work, as you need 3 parameters to invoke the wrapper properly in this example.

              – user1095108
              Nov 15 '18 at 17:56

















            myWeakLessOperator is a 2-parameter member function

            – Piotr Skotnicki
            Nov 15 '18 at 17:55





            myWeakLessOperator is a 2-parameter member function

            – Piotr Skotnicki
            Nov 15 '18 at 17:55













            @PiotrSkotnicki I just noticed that too, that doesn't seem very sensible though.

            – Pezo
            Nov 15 '18 at 17:56





            @PiotrSkotnicki I just noticed that too, that doesn't seem very sensible though.

            – Pezo
            Nov 15 '18 at 17:56













            I don't think this would work, as you need 3 parameters to invoke the wrapper properly in this example.

            – user1095108
            Nov 15 '18 at 17:56





            I don't think this would work, as you need 3 parameters to invoke the wrapper properly in this example.

            – user1095108
            Nov 15 '18 at 17:56











            1














            you can use std::bind, or some other wrapper.



            EXAMPLE:



            using namespace std::placeholders;
            Foo bar;
            std::unordered_set<Foo>::iterator minElement =
            std::min_element(std::begin(mySet),
            std::end(mySet),
            std::bind(&Foo::myWeakLessOperator, bar, _1, _2));


            OR



            Foo bar;
            std::unordered_set<Foo>::iterator minElement =
            std::min_element(std::begin(mySet),
            std::end(mySet),
            gnr::memfun<MEMFUN(Foo::myWeakLessOperator)>(bar));





            share|improve this answer


























            • Can you give an example, I am not used to std::bind and co, I cannot see how to use it.

              – Azias
              Nov 15 '18 at 18:30











            • Lambda is superior to everything, though, faster, takes up less space, ...

              – user1095108
              Nov 15 '18 at 18:53











            • I have tried with this example and it effectively does the job. thanks.

              – Azias
              Nov 16 '18 at 8:01











            • You should know that std::bind is a lambda precursor. Effectively, the lambda replaces it and is superior.

              – user1095108
              Nov 16 '18 at 12:24
















            1














            you can use std::bind, or some other wrapper.



            EXAMPLE:



            using namespace std::placeholders;
            Foo bar;
            std::unordered_set<Foo>::iterator minElement =
            std::min_element(std::begin(mySet),
            std::end(mySet),
            std::bind(&Foo::myWeakLessOperator, bar, _1, _2));


            OR



            Foo bar;
            std::unordered_set<Foo>::iterator minElement =
            std::min_element(std::begin(mySet),
            std::end(mySet),
            gnr::memfun<MEMFUN(Foo::myWeakLessOperator)>(bar));





            share|improve this answer


























            • Can you give an example, I am not used to std::bind and co, I cannot see how to use it.

              – Azias
              Nov 15 '18 at 18:30











            • Lambda is superior to everything, though, faster, takes up less space, ...

              – user1095108
              Nov 15 '18 at 18:53











            • I have tried with this example and it effectively does the job. thanks.

              – Azias
              Nov 16 '18 at 8:01











            • You should know that std::bind is a lambda precursor. Effectively, the lambda replaces it and is superior.

              – user1095108
              Nov 16 '18 at 12:24














            1












            1








            1







            you can use std::bind, or some other wrapper.



            EXAMPLE:



            using namespace std::placeholders;
            Foo bar;
            std::unordered_set<Foo>::iterator minElement =
            std::min_element(std::begin(mySet),
            std::end(mySet),
            std::bind(&Foo::myWeakLessOperator, bar, _1, _2));


            OR



            Foo bar;
            std::unordered_set<Foo>::iterator minElement =
            std::min_element(std::begin(mySet),
            std::end(mySet),
            gnr::memfun<MEMFUN(Foo::myWeakLessOperator)>(bar));





            share|improve this answer















            you can use std::bind, or some other wrapper.



            EXAMPLE:



            using namespace std::placeholders;
            Foo bar;
            std::unordered_set<Foo>::iterator minElement =
            std::min_element(std::begin(mySet),
            std::end(mySet),
            std::bind(&Foo::myWeakLessOperator, bar, _1, _2));


            OR



            Foo bar;
            std::unordered_set<Foo>::iterator minElement =
            std::min_element(std::begin(mySet),
            std::end(mySet),
            gnr::memfun<MEMFUN(Foo::myWeakLessOperator)>(bar));






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 16 '18 at 12:28

























            answered Nov 15 '18 at 17:56









            user1095108user1095108

            7,12133380




            7,12133380













            • Can you give an example, I am not used to std::bind and co, I cannot see how to use it.

              – Azias
              Nov 15 '18 at 18:30











            • Lambda is superior to everything, though, faster, takes up less space, ...

              – user1095108
              Nov 15 '18 at 18:53











            • I have tried with this example and it effectively does the job. thanks.

              – Azias
              Nov 16 '18 at 8:01











            • You should know that std::bind is a lambda precursor. Effectively, the lambda replaces it and is superior.

              – user1095108
              Nov 16 '18 at 12:24



















            • Can you give an example, I am not used to std::bind and co, I cannot see how to use it.

              – Azias
              Nov 15 '18 at 18:30











            • Lambda is superior to everything, though, faster, takes up less space, ...

              – user1095108
              Nov 15 '18 at 18:53











            • I have tried with this example and it effectively does the job. thanks.

              – Azias
              Nov 16 '18 at 8:01











            • You should know that std::bind is a lambda precursor. Effectively, the lambda replaces it and is superior.

              – user1095108
              Nov 16 '18 at 12:24

















            Can you give an example, I am not used to std::bind and co, I cannot see how to use it.

            – Azias
            Nov 15 '18 at 18:30





            Can you give an example, I am not used to std::bind and co, I cannot see how to use it.

            – Azias
            Nov 15 '18 at 18:30













            Lambda is superior to everything, though, faster, takes up less space, ...

            – user1095108
            Nov 15 '18 at 18:53





            Lambda is superior to everything, though, faster, takes up less space, ...

            – user1095108
            Nov 15 '18 at 18:53













            I have tried with this example and it effectively does the job. thanks.

            – Azias
            Nov 16 '18 at 8:01





            I have tried with this example and it effectively does the job. thanks.

            – Azias
            Nov 16 '18 at 8:01













            You should know that std::bind is a lambda precursor. Effectively, the lambda replaces it and is superior.

            – user1095108
            Nov 16 '18 at 12:24





            You should know that std::bind is a lambda precursor. Effectively, the lambda replaces it and is superior.

            – user1095108
            Nov 16 '18 at 12:24











            0














            The closest to what you want is maybe



            auto minElement =
            std::min_element(
            std::begin(mySet),
            std::end(mySet),
            mem_fun_functor(&Foo::myWeakLessOperator)
            );


            There is std::mem_fun (deprecated in c++11) and std::mem_fn both wrap a member function pointer, though both take a instance as parameter to invoke the member function. If you want a functor that wraps the object also, i think you need to write your own:



            auto mem_fun_functor = 
            [&bar](decltype(&Foo::myWeakLessOperator) f){
            return [f,&bar](const Foo& a,const Foo& b) {
            return (bar.*f)(a,b);
            };
            };


            However, given that none of the answers is really much shorter or leading to cleaner code, I would consider to just use your first version with the lambda (unless you maybe have many different member functions that you want to use as comparator).



            What do you actually mean by "simplifying" ? You do need to specify the object you want to call the member function on, you need to specify how you want to forward the parameters. Thats basically all the lambda does.



            Defering all this to a functor as for example above makes your code more complicated rather than simpler. In your first snippet anybody familiar with standard algorithms can look at that few lines of code and fully understand what is going on.



            Eventually it is a matter of style, and what you consider as readable, but being able to declare stuff in the most narrowest scope is one big advantage of using lambdas.






            share|improve this answer


























            • Correction: std::mem_fun was deprecated long ago and removed in C++17, you shouldn't use that. std::mem_fn is the way to go, it takes both references and pointers (raw or smart) as receivers.

              – Pezo
              Nov 15 '18 at 20:51











            • @Pezo thanks, corrected

              – user463035818
              Nov 15 '18 at 20:54











            • I really like your idea of returning a lambda, I never think of that.

              – Pezo
              Nov 15 '18 at 20:56











            • @Pezo my favourite is mjdmochowski's answer, though I really think just writing the lambda directly in the algorithm call is the most clean way. Its a bit of typing, but I prever to have everything in the most narrow scope. Whether there are reasons to pull something to a higher scope isnt really clear from the question

              – user463035818
              Nov 15 '18 at 21:00













            • I don't particularly like that solution since it'll waste space, because you need a reference/pointer to the containing object in the operator object (so it can access members).

              – Pezo
              Nov 16 '18 at 11:05
















            0














            The closest to what you want is maybe



            auto minElement =
            std::min_element(
            std::begin(mySet),
            std::end(mySet),
            mem_fun_functor(&Foo::myWeakLessOperator)
            );


            There is std::mem_fun (deprecated in c++11) and std::mem_fn both wrap a member function pointer, though both take a instance as parameter to invoke the member function. If you want a functor that wraps the object also, i think you need to write your own:



            auto mem_fun_functor = 
            [&bar](decltype(&Foo::myWeakLessOperator) f){
            return [f,&bar](const Foo& a,const Foo& b) {
            return (bar.*f)(a,b);
            };
            };


            However, given that none of the answers is really much shorter or leading to cleaner code, I would consider to just use your first version with the lambda (unless you maybe have many different member functions that you want to use as comparator).



            What do you actually mean by "simplifying" ? You do need to specify the object you want to call the member function on, you need to specify how you want to forward the parameters. Thats basically all the lambda does.



            Defering all this to a functor as for example above makes your code more complicated rather than simpler. In your first snippet anybody familiar with standard algorithms can look at that few lines of code and fully understand what is going on.



            Eventually it is a matter of style, and what you consider as readable, but being able to declare stuff in the most narrowest scope is one big advantage of using lambdas.






            share|improve this answer


























            • Correction: std::mem_fun was deprecated long ago and removed in C++17, you shouldn't use that. std::mem_fn is the way to go, it takes both references and pointers (raw or smart) as receivers.

              – Pezo
              Nov 15 '18 at 20:51











            • @Pezo thanks, corrected

              – user463035818
              Nov 15 '18 at 20:54











            • I really like your idea of returning a lambda, I never think of that.

              – Pezo
              Nov 15 '18 at 20:56











            • @Pezo my favourite is mjdmochowski's answer, though I really think just writing the lambda directly in the algorithm call is the most clean way. Its a bit of typing, but I prever to have everything in the most narrow scope. Whether there are reasons to pull something to a higher scope isnt really clear from the question

              – user463035818
              Nov 15 '18 at 21:00













            • I don't particularly like that solution since it'll waste space, because you need a reference/pointer to the containing object in the operator object (so it can access members).

              – Pezo
              Nov 16 '18 at 11:05














            0












            0








            0







            The closest to what you want is maybe



            auto minElement =
            std::min_element(
            std::begin(mySet),
            std::end(mySet),
            mem_fun_functor(&Foo::myWeakLessOperator)
            );


            There is std::mem_fun (deprecated in c++11) and std::mem_fn both wrap a member function pointer, though both take a instance as parameter to invoke the member function. If you want a functor that wraps the object also, i think you need to write your own:



            auto mem_fun_functor = 
            [&bar](decltype(&Foo::myWeakLessOperator) f){
            return [f,&bar](const Foo& a,const Foo& b) {
            return (bar.*f)(a,b);
            };
            };


            However, given that none of the answers is really much shorter or leading to cleaner code, I would consider to just use your first version with the lambda (unless you maybe have many different member functions that you want to use as comparator).



            What do you actually mean by "simplifying" ? You do need to specify the object you want to call the member function on, you need to specify how you want to forward the parameters. Thats basically all the lambda does.



            Defering all this to a functor as for example above makes your code more complicated rather than simpler. In your first snippet anybody familiar with standard algorithms can look at that few lines of code and fully understand what is going on.



            Eventually it is a matter of style, and what you consider as readable, but being able to declare stuff in the most narrowest scope is one big advantage of using lambdas.






            share|improve this answer















            The closest to what you want is maybe



            auto minElement =
            std::min_element(
            std::begin(mySet),
            std::end(mySet),
            mem_fun_functor(&Foo::myWeakLessOperator)
            );


            There is std::mem_fun (deprecated in c++11) and std::mem_fn both wrap a member function pointer, though both take a instance as parameter to invoke the member function. If you want a functor that wraps the object also, i think you need to write your own:



            auto mem_fun_functor = 
            [&bar](decltype(&Foo::myWeakLessOperator) f){
            return [f,&bar](const Foo& a,const Foo& b) {
            return (bar.*f)(a,b);
            };
            };


            However, given that none of the answers is really much shorter or leading to cleaner code, I would consider to just use your first version with the lambda (unless you maybe have many different member functions that you want to use as comparator).



            What do you actually mean by "simplifying" ? You do need to specify the object you want to call the member function on, you need to specify how you want to forward the parameters. Thats basically all the lambda does.



            Defering all this to a functor as for example above makes your code more complicated rather than simpler. In your first snippet anybody familiar with standard algorithms can look at that few lines of code and fully understand what is going on.



            Eventually it is a matter of style, and what you consider as readable, but being able to declare stuff in the most narrowest scope is one big advantage of using lambdas.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 15 '18 at 21:07

























            answered Nov 15 '18 at 20:25









            user463035818user463035818

            17.9k42868




            17.9k42868













            • Correction: std::mem_fun was deprecated long ago and removed in C++17, you shouldn't use that. std::mem_fn is the way to go, it takes both references and pointers (raw or smart) as receivers.

              – Pezo
              Nov 15 '18 at 20:51











            • @Pezo thanks, corrected

              – user463035818
              Nov 15 '18 at 20:54











            • I really like your idea of returning a lambda, I never think of that.

              – Pezo
              Nov 15 '18 at 20:56











            • @Pezo my favourite is mjdmochowski's answer, though I really think just writing the lambda directly in the algorithm call is the most clean way. Its a bit of typing, but I prever to have everything in the most narrow scope. Whether there are reasons to pull something to a higher scope isnt really clear from the question

              – user463035818
              Nov 15 '18 at 21:00













            • I don't particularly like that solution since it'll waste space, because you need a reference/pointer to the containing object in the operator object (so it can access members).

              – Pezo
              Nov 16 '18 at 11:05



















            • Correction: std::mem_fun was deprecated long ago and removed in C++17, you shouldn't use that. std::mem_fn is the way to go, it takes both references and pointers (raw or smart) as receivers.

              – Pezo
              Nov 15 '18 at 20:51











            • @Pezo thanks, corrected

              – user463035818
              Nov 15 '18 at 20:54











            • I really like your idea of returning a lambda, I never think of that.

              – Pezo
              Nov 15 '18 at 20:56











            • @Pezo my favourite is mjdmochowski's answer, though I really think just writing the lambda directly in the algorithm call is the most clean way. Its a bit of typing, but I prever to have everything in the most narrow scope. Whether there are reasons to pull something to a higher scope isnt really clear from the question

              – user463035818
              Nov 15 '18 at 21:00













            • I don't particularly like that solution since it'll waste space, because you need a reference/pointer to the containing object in the operator object (so it can access members).

              – Pezo
              Nov 16 '18 at 11:05

















            Correction: std::mem_fun was deprecated long ago and removed in C++17, you shouldn't use that. std::mem_fn is the way to go, it takes both references and pointers (raw or smart) as receivers.

            – Pezo
            Nov 15 '18 at 20:51





            Correction: std::mem_fun was deprecated long ago and removed in C++17, you shouldn't use that. std::mem_fn is the way to go, it takes both references and pointers (raw or smart) as receivers.

            – Pezo
            Nov 15 '18 at 20:51













            @Pezo thanks, corrected

            – user463035818
            Nov 15 '18 at 20:54





            @Pezo thanks, corrected

            – user463035818
            Nov 15 '18 at 20:54













            I really like your idea of returning a lambda, I never think of that.

            – Pezo
            Nov 15 '18 at 20:56





            I really like your idea of returning a lambda, I never think of that.

            – Pezo
            Nov 15 '18 at 20:56













            @Pezo my favourite is mjdmochowski's answer, though I really think just writing the lambda directly in the algorithm call is the most clean way. Its a bit of typing, but I prever to have everything in the most narrow scope. Whether there are reasons to pull something to a higher scope isnt really clear from the question

            – user463035818
            Nov 15 '18 at 21:00







            @Pezo my favourite is mjdmochowski's answer, though I really think just writing the lambda directly in the algorithm call is the most clean way. Its a bit of typing, but I prever to have everything in the most narrow scope. Whether there are reasons to pull something to a higher scope isnt really clear from the question

            – user463035818
            Nov 15 '18 at 21:00















            I don't particularly like that solution since it'll waste space, because you need a reference/pointer to the containing object in the operator object (so it can access members).

            – Pezo
            Nov 16 '18 at 11:05





            I don't particularly like that solution since it'll waste space, because you need a reference/pointer to the containing object in the operator object (so it can access members).

            – Pezo
            Nov 16 '18 at 11:05


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53325193%2fpass-a-member-function-as-compare-operator-for-c-standard-library-algorithm%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Bressuire

            Vorschmack

            Quarantine