web-dev-qa-db-fra.com

Comment utiliser les paramètres automatiques lambda en C ++ 11

J'ai un code en C++ 14. Cependant, quand je l'ai utilisé en C++ 11, il a une erreur à const auto. Comment l'utiliser en 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; });
26
A. John

C++ 11 ne prend pas en charge les lambdas génériques . C'est ce que auto dans la liste des paramètres de lambda signifie: un paramètre générique, comparable aux paramètres d'un modèle de fonction. (Notez que le const n'est pas le problème ici.)

Remarque: C++ 14 le fait supporte les lambdas avec auto, const auto, etc. Vous pouvez en lire plus ici .

Vous avez essentiellement deux options:

  1. Tapez le type correct au lieu de auto. Ici, c'est le type d'élément de X, qui est pair<double, vector<int>>. Si vous trouvez cela illisible, un typedef peut vous aider.

    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. Remplacez le lambda par un foncteur qui a un modèle d'opérateur d'appel. C'est ainsi que les lambdas génériques sont fondamentalement implémentés en coulisse. Le lambda est très générique, alors pensez à le mettre dans un en-tête d'utilitaire global. (Cependant, ne pas using namespace std; mais tapez std:: au cas où vous le mettriez dans un en-tête.)

    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());
    
29
leemes

Je sais qu'il existe une réponse acceptée, mais vous pouvez également utiliser decltype en C++ 11 pour cela, cela semble un peu compliqué ...

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

Utilisez cbegin() ici pour obtenir la constante value_type Constante du conteneur.

11
Nim

Malheureusement, les lambdas génériques qui prennent auto (que const ou non) soit une fonctionnalité C++ 14 uniquement.

Voir ici https://isocpp.org/wiki/faq/cpp14-language#generic-lambdas pour plus de détails.

9
Rich L

const auto n'est pas pris en charge dans C++ 11 en tant que paramètre lambda (en fait, les lambdas génériques ne sont pas pris en charge dans C++ 11).

Pour corriger:

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; });
3
utnapistim

Vous pouvez également utiliser directement le value_type typedef du conteneur avec un decltype, comme

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