How to sort with a lambda?
225,048
Solution 1
Got it.
sort(mMyClassVector.begin(), mMyClassVector.end(),
[](const MyClass & a, const MyClass & b) -> bool
{
return a.mProperty > b.mProperty;
});
I assumed it'd figure out that the > operator returned a bool (per documentation). But apparently it is not so.
Solution 2
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;
}
Solution 3
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,
Related videos on Youtube
Author by
BTR
Updated on March 16, 2022Comments
-
BTR about 2 years
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)
.-
BTR about 13 yearsThe vector is of a struct which contains an integer and two strings. The property here would be an integer.
-
GManNickG about 13 yearsShow us a small compilable example.
-
-
sellibitze about 13 yearsWhat 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. -
BTR about 13 yearsThen 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 about 13 yearsYeah, 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 about 13 yearsAnd yes, the property is int32_t.
-
BTR about 13 yearsHey GMan, I noticed that you have found Lambda bugs with VS per your site: gmannickg.com/?p=38. Possibly related issue in the Express edition?
-
Warpspace over 10 yearsShouldn't it be
operator<
, notoperator>
? -
pancake almost 10 yearsYes 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! -
David Grayson almost 8 yearsI just tried this in GCC 5.3.0 and the
-> bool
part is not needed. -
Conrad Jones about 5 yearsit was highly likely explicitly specifying the -> boot return type was required due to a VC bug.
-
Admin over 3 yearsmake it longer, thats why op wants to use a lambda