Подтвердить что ты не робот

Как использовать автоматические параметры лямбда в С++ 11

У меня есть код в С++ 14. Однако, когда я использовал его в С++ 11, он имеет ошибку при const auto. Как использовать его в С++ 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; });
4b9b3361

Ответ 1

С++ 11 не поддерживает общие лямбды. То, что на самом деле означает auto в списке лямбда-параметров: универсальный параметр, сравнимый с параметрами в шаблоне функции. (Обратите внимание, что const здесь не проблема.)

Примечание: С++ 14 поддерживает лямбды с auto, const auto и т.д. Вы можете прочитать об этом здесь.

У вас есть в основном два варианта:

  1. Введите правильный тип вместо auto. Здесь это тип элемента X, который представляет собой pair<double, vector<int>>. Если вы обнаружите, что это нечитабельно, 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. Замените лямбду на функтор с шаблоном оператора вызова. Вот как общие лямбды в основном реализуются за сценой. Лямбда очень универсальная, так что подумайте над тем, чтобы поместить ее в глобальный служебный заголовок. (Однако не using namespace std; введите std:: на случай, если вы поместите его в заголовок.)

    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

Я знаю, что есть принятый ответ, но вы также можете использовать decltype в С++ 11 для этого, он выглядит немного грязным...

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

Используйте cbegin() здесь, когда вы получите const const value_type в контейнере.

Ответ 3

К сожалению, общие lambdas, которые принимают auto (независимо от того, является ли const или нет), являются только функцией С++ 14.

Подробнее см. здесь https://isocpp.org/wiki/faq/cpp14-language#generic-lambdas.

Ответ 4

const auto не поддерживается в С++ 11 в качестве параметра лямбда (фактически генерируемые lambdas не поддерживаются в С++ 11).

Чтобы исправить:

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

В качестве альтернативы вы можете напрямую использовать value_type typedef контейнера с decltype, например

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