A replacement for std::bind2nd

前端 未结 3 868
轻奢々
轻奢々 2021-01-01 22:41

I have a foo which is a std::vector. It represents the \"edge\" values for a set of ranges.

For example, if foo is

相关标签:
3条回答
  • 2021-01-01 22:50

    What about going straight from Stone Age (bind2nd) to the Iron Age with a C++14 generic lambda, bypassing the Bronze Age (bind)?

    std::find_if(foo.begin(), foo.end(), [&](auto const& elem) { 
        return elem > bar; 
    }); 
    

    And if the input is sorted

    std::lower_bound(foo.begin(), foo.end(), bar); 
    

    Lambdas read much easier and are also easier to inline than std::bind expresions. See e.g. Lavevej's CppCon 2015 talk.

    0 讨论(0)
  • 2021-01-01 22:51

    In C++11, you can use std::bind; it just isn't as obvious how to use it:

    #include <functional>
    using namespace std::placeholders;
    std::find_if(
        foo.begin(),
        foo.end(),
        // create a unary function object that invokes greater<int>::operator()
        // with the single parameter passed as the first argument and `bar` 
        // passed as the second argument
        std::bind(std::greater<int>(), _1, bar)
    ) - foo().begin() - 1;
    

    The key is the use of the placeholder argument, which are declared in the std::placeholders namespace. std::bind returns a function object that takes some number of parameters when it is invoked. The placeholders used inside the call to std::bind show how the arguments provided when the resulting object is invoked map to the argument list to the callable that you're binding to. So, for instance:

    auto op1 = std::bind(std::greater<int>(), _1, bar);
    op1(5); // equivalent to std::greater<int>()(5, bar)
    
    auto op2 = std::bind(std::greater<int>(), bar, _1);
    op2(5); // equivalent to std::greater<int>()(bar, 5)
    
    auto op3 = std::bind(std::greater<int>(), _2, _1);
    op3(5, bar); // equivalent to std::greater<int>()(bar, 5)
    
    auto op4 = std::bind(std::greater<int>(), _1, _2);
    op4(5, bar); // equivalent to std::greater<int>()(5, bar)
    
    0 讨论(0)
  • 2021-01-01 22:57

    bind version would be:

    bind(std::greater<int>(), placeholders::_1, bar)
    

    but I think, it is more encouraged to use lambdas, as in:

    [bar](const int a){return bar < a;}
    

    It is also encouraged to use overloaded functions begin/end instead of method calls. so it would be like:

    find_if(begin(foo), end(foo), [bar](const int a){return bar < a;})
    
    0 讨论(0)
提交回复
热议问题