198
sort(mMyClassVector.begin(), mMyClassVector.end(), 
    [](const MyClass & a, const MyClass & b)
{ 
    return a.mProperty > b.mProperty; 
});

I'd like to use a lambda function to sort custom classes in place of binding an instance method. However, the code above yields the error:

error C2564: 'const char *' : a function-style conversion to a built-in type can only take one argument

It works fine with boost::bind(&MyApp::myMethod, this, _1, _2).

BartoszKP
  • 34,786
  • 15
  • 102
  • 130
BTR
  • 4,880
  • 4
  • 24
  • 21

4 Answers4

233

Got it.

Ascending:

std::ranges::sort(mMyClassVector, [](const MyClass &a, const MyClass &b)
{ 
    return a.mProperty < b.mProperty; 
});

Descending:

std::ranges::sort(mMyClassVector, [](const MyClass &a, const MyClass &b)
{ 
    return a.mProperty > b.mProperty; 
});

When using an older standard than C++20, you can use std::sort(mMyClassVector.begin(), mMyClassVector.end(), ...) instead.

BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185
BTR
  • 4,880
  • 4
  • 24
  • 21
  • 2
    What you have written so far makes little sense. If mProperty is supposed to be an int `a.mProperty>b.mProperty` will definitely yield a bool. – sellibitze Feb 26 '11 at 00:32
  • 1
    Then you understand my confusion. I think it might be something weird with my VC10 Express (no service pack). I moved the project onto a machine with Visual Studio 2010 Team and it worked without the "-> bool". – BTR Feb 26 '11 at 00:59
  • And yes, the property is int32_t. – BTR Feb 26 '11 at 01:05
  • Hey GMan, I noticed that you have found Lambda bugs with VS per your site: http://www.gmannickg.com/?p=38. Possibly related issue in the Express edition? – BTR Mar 11 '11 at 19:38
  • 11
    Shouldn't it be `operator<`, not `operator>`? – Warpspace Sep 11 '13 at 10:02
  • 14
    Yes it should be ``<``, for standard ascending order. I edited the answer to make it clear it was a descending sort but apparently my edit was unhelpful and got wiped! – pancake Jun 29 '14 at 22:15
  • 3
    I just tried this in GCC 5.3.0 and the `-> bool` part is not needed. – David Grayson Jun 26 '16 at 07:58
  • 5
    it was highly likely explicitly specifying the -> boot return type was required due to a VC bug. – Conrad Jones Mar 16 '19 at 14:18
  • I found that I needed to use pointers `[] (const MyClass * a, const MyClass * b)` when I used `stable_sort`. – Flip Mar 13 '23 at 13:32
37

You can use it like this:

#include<array>
#include<functional>
using namespace std;
int main()
{
    array<int, 10> arr = { 1,2,3,4,5,6,7,8,9 };

    sort(begin(arr), 
         end(arr), 
         [](int a, int b) {return a > b; });

    for (auto item : arr)
      cout << item << " ";

    return 0;
}
Adrian
  • 947
  • 1
  • 12
  • 24
6

Can the problem be with the "a.mProperty > b.mProperty" line? I've gotten the following code to work:

#include <algorithm>
#include <vector>
#include <iterator>
#include <iostream>
#include <sstream>

struct Foo
{
    Foo() : _i(0) {};

    int _i;

    friend std::ostream& operator<<(std::ostream& os, const Foo& f)
    {
        os << f._i;
        return os;
    };
};

typedef std::vector<Foo> VectorT;

std::string toString(const VectorT& v)
{
    std::stringstream ss;
    std::copy(v.begin(), v.end(), std::ostream_iterator<Foo>(ss, ", "));
    return ss.str();
};

int main()
{

    VectorT v(10);
    std::for_each(v.begin(), v.end(),
            [](Foo& f)
            {
                f._i = rand() % 100;
            });

    std::cout << "before sort: " << toString(v) << "\n";

    sort(v.begin(), v.end(),
            [](const Foo& a, const Foo& b)
            {
                return a._i > b._i;
            });

    std::cout << "after sort:  " << toString(v) << "\n";
    return 1;
};

The output is:

before sort: 83, 86, 77, 15, 93, 35, 86, 92, 49, 21,
after sort:  93, 92, 86, 86, 83, 77, 49, 35, 21, 15,
Stephan
  • 1,007
  • 7
  • 9
  • Yeah, something screwy with the setup I was on. Compiling on my laptop without it just fine on the Team edition of Visual Studio 2010. What clued me in what that I'd switched back to bind and the error wouldn't go away. I was on VC10 Express. Bug? – BTR Feb 26 '11 at 01:03
  • make it longer, thats why op wants to use a lambda –  Jan 29 '21 at 08:04
3

You can sort an array like this:

#include <bits/stdc++.h>
using namespace std;
int main() {
    int q[] = {1, 3, 5, 7, 9, 2, 4, 6, 8 ,10};
    sort(q, q + 10, [&](int A, int B) { return A < B; });
    for (int i = 0; i < 10; i++)
        cout << q[i] << ' ';
    return 0;
}
before sort: 1 3 5 7 9 2 4 6 8 10
after sort: 1 2 3 4 5 6 7 8 9 10 

I'd always like to use lambda to sort a array of struct in acm contests like this:

struct item {
    int a, b;
};

vector<item> q;

sort(q.begin(), q.end(), [&](item t1, item t2) {
    return t1.a < t2.a;
});

Heyya
  • 43
  • 8