C ++ Найти строку в списке структур со старым компилятором GCC 4.4.0 - PullRequest
0 голосов
/ 22 октября 2019

Я работаю над программой, имеющей список на основе структуры, в котором хранятся некоторые данные атрибутов файла.

struct files {
  string name;
  string size;
  string owner;
};

И переменная списка описана ниже

list<files> myfilecollection;

То, чтоЯ хочу сделать, это проверить, содержится ли определенное имя файла в myfilecollection. В основном я проверил этот пример пост и попытался написать эту функцию:

bool isFileSensible(const string& filename)
{
    auto match = std::find_if(myfilecollection.cbegin(), myfilecollection.cend(), [name] (const files& s) {
        return s.name == filename;
    });

    return match != myfilecollection.cend();
}

Эта реализация хорошо работает с GCC 9.2.0, но мне нужно, чтобы эта функция работала на GCC4.4.4 с не совместимы даже с C ++ 11. Каков наилучший способ повторно реализовать эту функцию для GCC 4.4.0?

С уважением, Ф.Боргес

Ответы [ 2 ]

3 голосов
/ 22 октября 2019

Лямбда - это не более чем короткая форма для написания функтора. Вы можете просто вернуться к написанию функтора, который ведет себя так же, как

bool isFileSensible(const string& filename)
{
    struct FindFilename
    {
        std::string filename;
        FindFilename(std::string filename) : filename(filename) {}
        bool operator()(const files& obj)
        {
            return obj.name == filename;
        }
    };
    std::list<files>::const_iterator match = std::find_if(myfilecollection.cbegin(), myfilecollection.cend(), FindFilename(filename));
    return match != myfilecollection.cend();
}

Я поместил FindFilename в область действия функции, чтобы она не загрязняла глобальное пространство имен. Если вы хотите использовать этот функтор в другом месте, вы можете переместить его в глобальную область.

3 голосов
/ 22 октября 2019

Вы используете auto и лямбду, которые оба являются C ++ 11. К счастью, в вашем случае оба могут быть заменены тривиально.

Лямбды - это просто синтаксический сахар для классов функторов, поэтому вы можете использовать вместо них:

struct compare_files_by_name {
    std::string target;
    compare_files_by_name(const std::string& target) : target(target) {}
    bool operator()(const files& f) {
        return f.name == target;
    }
};

И то, что find_if возвращаетlist<files>::const_iterator. Если сложить это вместе, вы получите:

bool isFileSensible(const string& filename)
{
    compare_files_by_name comp(filename);
    std::list<files>::const_iterator match = std::find_if(myfilecollection.cbegin(), myfilecollection.cend(),comp);

    return match != myfilecollection.cend();
}

PS: Привыкнув к auto, я нахожу странным полностью выписать тип итератора. Я, вероятно, написал бы это как

  return myfilecollection.cend() != std::find_if(....

просто, чтобы не указывать тип итератора.

...