How to use lambda auto parameters in C++11

做~自己de王妃 提交于 2019-12-17 23:24:49

问题


I have a code in C++14. However, when I used it in C++11, it has an error at const auto. How to use it 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; });

回答1:


C++11 doesn't support generic lambdas. That's what auto in the lambda's parameter list actually stands for: a generic parameter, comparable to parameters in a function template. (Note that the const isn't the problem here.)

Note: C++14 does support lambdas with auto, const auto, etc. You can read about it here.

You have basically two options:

  1. Type out the correct type instead of auto. Here it is the element type of X, which is pair<double, vector<int>>. If you find this unreadable, a typedef can help.

    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. Replace the lambda with a functor which has a call operator template. That's how generic lambdas are basically implemented behind the scene. The lambda is very generic, so consider putting it in some global utility header. (However do not using namespace std; but type out std:: in case you put it in a header.)

    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:


I know there is an accepted answer, but you can also use decltype in C++11 for this, it looks a bit messy...

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

Use cbegin() here as you get the const correct value_type of the container.




回答3:


Unfortunately, generic lambdas that take auto (whether const or not) is a C++14 only feature.

See here https://isocpp.org/wiki/faq/cpp14-language#generic-lambdas for some more details.




回答4:


const auto is not supported in C++11 as a lambda parameter (actually generic lambdas are not supported in C++11).

To fix:

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



回答5:


Alternatively you can directly use the value_type typedef of the container with a decltype, like

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


来源:https://stackoverflow.com/questions/30071453/how-to-use-lambda-auto-parameters-in-c11

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!