2015-05-06 14 views
22

Ho un codice in C++ 14. Tuttavia, quando l'ho usato in C++ 11, ha un errore a const auto. Come si usa in C++ 11?Come utilizzare i parametri auto lambda in 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

Sì, modifiche che cambiano radicalmente la questione non sono realmente appropriato qui, ho rimosso. Capisco che tu non pubblichi molto qui e che ciò che hai fatto * sia * comunemente accettato nei forum, quindi posso capire perché l'hai fatto, ma va bene chiedere molte altre domande correlate qui, a patto che siano tutte buone domande che hanno senso da sole. – hvd

risposta

27

C++ 11 non supporta lambda generici. Questo è ciò che auto nella lista dei parametri lambda rappresenta in realtà: un parametro generico, paragonabile ai parametri in un modello di funzione. (Si noti che il const non è il problema qui.)

Hai fondamentalmente due opzioni :

  1. Digitare il tipo corretto invece di auto. Qui è il tipo di elemento di X, che è pair<double, vector<int>>. Se trovi questo illeggibile, un typedef può aiutarti.

    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. Sostituire la lambda con un funtore che ha un modello di operatore di chiamata. Ecco come i lambda generici sono fondamentalmente implementati dietro la scena. Il lambda è molto generico, quindi considera di inserirlo in un header di utilità globale. (Tuttavia non using namespace std; ma digitare fuori std:: nel caso in cui lo metti in un colpo di testa.)

    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 non è supportato in C++ 11 come parametro lambda (in realtà i lambda non sono supportati in C++ 11).

Per fissare:

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

So che c'è una risposta accettata, ma si può anche utilizzare decltype in C++ 11 per questo, sembra un po 'confuso ...

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

Utilizzare cbegin() qui come si ottiene il const corretto value_type del contenitore.

2

In alternativa è possibile utilizzare direttamente il typedef value_type del contenitore con un decltype, come

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

Se non sbaglio, puoi semplicemente digitare 'X.value_type' invece di' decltype (X) :: value_type'. – leemes

+2

@leemes Non penso, 'value_type' è un' typedef nidificato 'quindi è necessario l'accesso all'ambito tramite '::'. In diretta [qui] (http://ideone.com/fAMF40) e domanda correlata [qui] (http://stackoverflow.com/q/21290875/3093378). – vsoftco

+0

Grazie, quindi sono felice che il mio cervello abbia lanciato un avvertimento quando ho pensato che fosse possibile. – leemes