2015-05-06 18 views
22

Mam kod w C++ 14. Jednak, gdy użyłem go w C++ 11, ma błąd na const auto. Jak korzystać z niego w C++ 11?Jak używać parametrów auto lambda w C++ 11

vector<vector <int> > P; 
std::vector<double> f; 
vector< pair<double, vector<int> > > X; 
for (int i=0;i<N;i++) 
     X.push_back(make_pair(f[i],P[i])); 

////Sorting fitness descending order 
stable_sort(X.rbegin(), X.rend()); 
std::stable_sort(X.rbegin(), X.rend(), 
       [](const auto&lhs, const auto& rhs) { return lhs.first < rhs.first; }); 
+4

Tak, edycje, które zasadniczo zmienić pytanie tak naprawdę nie są odpowiednie tutaj, usunęliśmy je. Rozumiem, że nie publikujesz tutaj zbyt wiele i że to, co zrobiłeś * jest * powszechnie akceptowane na forach, więc mogę zrozumieć, dlaczego to zrobiłeś, ale jest w porządku zadawać mnóstwo powiązanych osobnych pytań tutaj, o ile są one wszystkie dobre pytania, które mają sens same w sobie. – hvd

Odpowiedz

27

C++ 11 nie obsługuje lambdy rodzajowe. Tak naprawdę jest to auto w liście parametrów lambda: parametr ogólny, porównywalny z parametrami w szablonie funkcji. (Zauważ, że const nie jest problemem tutaj).

Masz w zasadzie dwie opcje:

  1. Wpisz zewnątrz prawidłowy typ zamiast auto. Tutaj jest typ elementu X, który jest pair<double, vector<int>>. Jeśli uznasz to za nieczytelne, pomoże ci typedef.

    std::stable_sort(X.rbegin(), X.rend(), 
           [](const pair<double, vector<int>> & lhs, 
            const pair<double, vector<int>> & rhs) 
           { return lhs.first < rhs.first; }); 
    
  2. Wymienić lambda z funktora który ma połączenia operatora szablon. W ten sposób generyczne lambdy są zasadniczo realizowane za sceną. Wartość lambda jest bardzo ogólna, należy więc rozważyć umieszczenie jej w nagłówku globalnego narzędzia. (Jednak NIE using namespace std; ale wpisać się std:: w przypadku go umieścić w nagłówku.)

    struct CompareFirst { 
        template <class Fst, class Snd> 
        bool operator()(const pair<Fst,Snd>& l, const pair<Fst,Snd>& r) const { 
         return l.first < r.first; 
        } 
    }; 
    
    std::stable_sort(X.rbegin(), X.rend(), CompareFirst()); 
    
2

const auto nie jest obsługiwany w C++ 11 jako parametr lambda (w rzeczywistości ogólny lambdas nie jest obsługiwany w C++ 11).

Aby rozwiązać:

using pair_type = std::pair<double, std::vector<int>>; 
vector<pair_type> X; 

std::stable_sort(X.rbegin(), X.rend(), 
       [](const pair_type&lhs, const pair_type& rhs) 
       { return lhs.first < rhs.first; }); 
8

wiem, że jest akceptowane odpowiedź, ale można też użyć decltype w C++ 11 za to, że wygląda trochę brudny ...

stable_sort(X.rbegin(), X.rend(), [](decltype(*X.cbegin()) lhs, decltype(lhs) rhs) { return lhs.first < rhs.first; }); 

Należy użyć tutaj cbegin(), ponieważ otrzymujemy poprawną wartość stałej kontenera value_type.

2

Alternatywnie można korzystać bezpośrednio z value_type typedef pojemnika z decltype, jak

std::stable_sort(X.rbegin(), X.rend(), 
       [](const decltype(X)::value_type & lhs, 
        const decltype(X)::value_type & rhs) 
        {return lhs.first < rhs.first; } 
       ); 
+0

Jeśli się nie mylę, po prostu wpisz 'X.value_type' zamiast' decltype (X) :: value_type'. – leemes

+2

@leem nie wydaje mi się, że 'value_type' jest zagnieżdżonym' typedef', więc potrzebujesz dostępu do zakresu przez '::'. Na żywo [tutaj] (http://ideone.com/fAMF40) i pokrewne pytanie [tutaj] (http://stackoverflow.com/q/21290875/3093378). – vsoftco

+0

Dzięki, jestem szczęśliwy, że mój mózg rzucił ostrzeżenie, gdy myślałem, że jest to możliwe. – leemes