How to implement a lambda function for a sorting algorithm involving members of an object, indirectness and casting?

I am working on some code, and I have a section where I do one sorting function. To implement it, I decided that the easiest way is to overload the operator <function. What I would prefer to do is move the sort implementation closer to the actual call using some kind of boost :: bind, boost :: phoenix, lambda or some other type of implementation. Unfortunately, I do not have access to the new C ++ 11 features. The following is an example code.

// In a header
struct foo
{
   char * a;
   char * c_str() { return a; }
}

// In a header
struct bar
{
    foo * X;          

    bar(foo * _X) : X(_X) {}
    bool operator < (const bar& rhs) const
    {
        return std::string(X->c_str()) < std::string(rhs.X->c_str());
    }
};

struct bars : public std::vector<bar> { ... some stuff  };

// Some other header
bars Bs;


// A cpp file
... other stuff happens that fills the Xs vector with objects

...::Function()
{
    // Current use and it works fine
    std::sort(Bs.begin(), Bs.end())

    // Would like something that accomplishes this:
    // std::sort(Bs.begin(), Bs.end(), 
    //   std::string(lhs.X->c_str()) < std::string(rhs.X->c_str()))

    // A non-working example of what I'm trying to do
    // std::sort(Xs.begin(), Xs.end(), 
    //     std::string((bind(bar::X->c_str(), _1)) <
    //     std::string((bind(bar::X->c_str(), _2)) )
}

I get lost when trying to figure out how to access member pointers, member functions, and then pass the result to boost :: bind function.

Thank you for your help.

+3
source share
1

, ,

  • Boost Phoenix bind lambda
  • Boost Bind protect

. . , . . .

, , , , . "" ( ), .

, , , .

, , - /extract/ . , :

  • c_str() X lhs
  • c_str() X rhs

- . , :

template <typename F>
struct compare_by_impl {
    compare_by_impl(F f = F{}) : _f(std::move(f)) {}

    template <typename T, typename U>
    bool operator()(T const& a, U const& b) const {
        return _f(a) < _f(b);
    }
  private:
    F _f;
};

, factory, ( , Phoenix , , (arcane) , ):

template <typename Accessor>
compare_by_impl<Accessor> comparer_by(Accessor&& f) {
    return compare_by_impl<Accessor>(std::forward<Accessor>(f));
}

:

void Function()
{
    struct accessX_c_str {
        std::string operator()(bar const& b) const { 
            return b.X->c_str();
        }
    };

    std::sort(Bs.begin(), Bs.end(), comparer_by(accessX_c_str()));
}

.

:

// to avoid `comparer_by`
std::sort(Bs.begin(), Bs.end(), phx::bind(accessX_c_str(), arg1) < phx::bind(accessX_c_str(), arg2));


// to avoid any helper types (!?!?!? untested!)
std::sort(Bs.begin(), Bs.end(), 
        phx::construct<std::string>(phx::bind(&foo::c_str, phx::lambda [ phx::bind(&bar::X, arg1) ](arg1))) 
      < phx::construct<std::string>(phx::bind(&foo::c_str, phx::lambda [ phx::bind(&bar::X, arg1) ](arg2)))
    );
+1

All Articles