【问题标题】:C++ Find a string in struct list with old compiler GCC 4.4.0C++ 使用旧编译器 GCC 4.4.0 在结构列表中查找字符串
【发布时间】:2019-10-22 18:39:36
【问题描述】:

我正在开发一个程序,它有一个基于结构的列表来存储一些文件属性数据。

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

列表变量如下所述

list<files> myfilecollection;

我想要做的是检查某些确定的文件名是否包含在 myfilecollection 中。基本上我检查了这个example 帖子并尝试编写这个函数:

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 上工作得很好,但我需要让这个函数在 GCC 4.4.4 上工作,甚至不兼容 C++ 11。为 GCC 4.4.0 重新实现此功能的最佳方法是什么?

最好的问候, F.博尔赫斯

【问题讨论】:

    标签: c++ list struct find


    【解决方案1】:

    lambda 只不过是编写函子的简短形式。你可以回到编写一个行为方式相同的仿函数

    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 放在函数的范围内,这样它就不会污染全局命名空间。如果你想在其他地方重用这个函子,你可以把它移到全局范围内。

    【讨论】:

    • std::string filename 之后缺少; 而你仍然有auto
    • @foreknownas_463035818 好地方。答案已更新。
    • 除了你把左括号放在错误的地方,我们的答案几乎是一样的:P
    • 好吧,我想说我更喜欢你对比较器的内联定义,但这不也仅限于 C++11 吗?
    • @fborges22 抱歉,我打错了。应该是bool operator()(const files&amp; obj) 而不是bool operator()(const file&amp; obj)
    【解决方案2】:

    您正在使用 auto 和 lambda,它们都是 C++11。幸运的是,在您的情况下,两者都可以轻松替换。

    Lambda 基本上只是仿函数类的语法糖,因此您可以使用它:

    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&lt;files&gt;::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(....
    

    只是为了避免拼写迭代器类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-03
      • 2011-09-08
      • 2020-08-15
      • 2018-04-18
      • 1970-01-01
      • 2015-02-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多