Bir lambda ile nasıl sıralama yapılır?


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

Bir örnek yöntemini bağlama yerine özel sınıfları sıralamak için bir lambda işlevi kullanmak istiyorum. Bununla birlikte, yukarıdaki kod şu hatayı verir:

hata C2564: 'const char *': yerleşik bir türe işlev tarzı dönüştürme yalnızca bir bağımsız değişken alabilir

İle iyi çalışıyor boost::bind(&MyApp::myMethod, this, _1, _2).


Vektör, bir tamsayı ve iki dizgi içeren bir yapıya sahiptir. Buradaki özellik bir tamsayı olacaktır.
BTR

4
Bize derlenebilir küçük bir örnek gösterin .
GManNickG

Yanıtlar:


159

Anladım.

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

> Operatörünün bir bool (dokümantasyon başına) döndürdüğünü anlayacağını varsaydım. Ama görünüşe göre öyle değil.


40
O operator>zaman ne kadar kötü.
GManNickG

2
Şimdiye kadar yazdıklarınız pek mantıklı değil. MProperty'nin bir int olması gerekiyorsa a.mProperty>b.mProperty, kesinlikle bir bool verecektir.
sellibitze

1
O zaman kafa karışıklığımı anlıyorsun. VC10 Express'imde (servis paketi yok) garip bir şey olabileceğini düşünüyorum. Projeyi Visual Studio 2010 Team ile bir makineye taşıdım ve "-> bool" olmadan çalıştı.
BTR

8
Olması operator<gerekmiyor operator>mu?
Warpspace

8
Evet <, standart artan sıra için olmalıdır . Yanıtı, azalan bir sıralama olduğunu netleştirmek için düzenledim ama görünüşe göre düzenlemem yardımcı olmadı ve silindi!
pankek

19

Çoğu kod için, bunu şu şekilde kullanabilirsiniz:

#include<array>
#include<functional>

int main()
{
    std::array<int, 10> vec = { 1,2,3,4,5,6,7,8,9 };

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

    for (auto item : vec)
      std::cout << item << " ";

    return 0;
}

"Vec" yi sınıfınızla değiştirin, işte bu kadar.


Cevabınız BTR'den ne kadar farklı? Btw. daha fazla c ++ 11 yapmak için std :: begin (vec) ve std :: end (vec) kullanabilirsiniz.
Logman

Üzgünüm, bunu nasıl kaçırdım bilmiyorum. Gözlerim Stephan karakolunda duruyor. Benim hatam (önerilerinizden sonra
Adrian

5

Sorun "a.mProperty> b.mProperty" satırında olabilir mi? Çalışmak için aşağıdaki kodu aldım:

#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;
};

Çıktı:

before sort: 83, 86, 77, 15, 93, 35, 86, 92, 49, 21,
after sort:  93, 92, 86, 86, 83, 77, 49, 35, 21, 15,

Evet, yaptığım kurulumla ilgili garip bir şey. Dizüstü bilgisayarımda onsuz derlemek, Visual Studio 2010'un Takım sürümünde gayet iyi. Bağlamaya geri döndüğümde bana ipucu veren ve hata ortadan kalkmayacaktı. VC10 Express'teydim. Hata?
BTR
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.