【问题标题】:C++ lambda syntaxC++ lambda 语法
【发布时间】:2019-08-10 02:45:15
【问题描述】:

我有一个函数可以搜索迭代器向量,如果它的名称与作为参数传递的字符串匹配,则返回迭代器。

koalaGraph::PVertex lookUpByName(std::string Name, std::vector<koalaGraph::PVertex>& Vertices) {

    for (size_t i = 0; i < Vertices.size(); i++) {

        if(Vertices[i]->info.name == Name) 
            return Vertices[i];
    }
}

我的问题是如何将其实现为 lambda,以将其与 std::find_if 结合使用?

我正在尝试这个:

std::vector<koalaGraph::PVertex> V;
std::string Name;
std::find_if(V.begin(), V.end(), [&Name]() {return Name == V->info.name;})

但它说V

不能在 lambda 主体中引用封闭函数局部变量,除非它在捕获列表中。

【问题讨论】:

  • No return 如果没有找到?

标签: c++ lambda


【解决方案1】:

find_if 会将向量的元素传递给您的 lambda。这意味着你需要

std::find_if(V.begin(), V.end(), [&Name](auto const& V) {return Name == V->info.name;})

因此 lambda 主体中的 V 是向量的元素,而不是向量本身。


理想情况下,您应该给它一个不同于V 的名称,这样您就可以将向量和局部变量分开,就像

std::find_if(V.begin(), V.end(), [&Name](auto const& element) {return Name == elememt->info.name;})

所以现在很明显,您正在处理向量的一个元素,而不是向量本身。

【讨论】:

    【解决方案2】:

    首先,V-&gt;info.name 在 lambda 内部或外部的格式不正确。

    发送到算法std::find_if 的函数对象必须是一元函数。它必须将当前元素作为参数进行检查。

    auto found = std::find_if(
        V.begin(), V.end(), 
        [&Name](koalaGraph::PVertex const& item_to_check) {
            return Name == item_to_check->info.name;
        }
    );
    

    found 的类型是已找到元素的迭代器。如果没有找到,则返回V.end()

    如果您使用 C++14 或更高版本,您甚至可以使用通用 lambda:

    auto found = std::find_if(
        V.begin(), V.end(), 
        [&Name](auto const& item_to_check) {
            return Name == item_to_check->info.name;
        }
    );
    

    【讨论】:

    • V-&gt;info.name 是有效的语法。它只是不会进行类型检查,因为向量不会重载-&gt;
    • It just won't typecheck since vectors don't overload -&gt; 所以......它不会编译?在不重载 operator-&gt; 的类型对象上使用 -&gt; 是一种无效语法
    • 并非所有编译错误都是语法错误。见syntax vs. semantics
    • @SilvioMayolo 你链接我的答案说语义是程序的含义,通常在它的运行时行为中。我引用的代码只是格式错误,还没有语义。或者我没有正确理解这个概念
    【解决方案3】:

    std::find_if 的谓词将依次接收对范围内每个元素的引用。你需要:

    std::find_if(
        V.begin(), V.end(),
        [&Name](koalaGraph::PVertex const &v) { return Name == v->info.name; }
    );
    

    【讨论】:

      【解决方案4】:

      获取 V 作为 lambda 的参数。

      std::find_if(V.begin(), V.end(), [&amp;Name](type&amp; V) {return Name == V-&gt;info.name;)

      【讨论】:

        【解决方案5】:

        使用const auto &amp; 在 lambda 表达式中访问向量中的各个元素。由于向量是左值,因此 auto 将被推导出为const vector&lt;PVertex&gt; &amp;。然后,您可以使用std::distance 查找该对象在向量中的元素位置。

        struct PVertex
        {
            std::string name;
        };
        
        int main()
        {
            std::vector<PVertex> V = {{"foo"},{"bar"},{"cat"},{"dog"}};
        
            std::string Name = "cat";
        
            auto found = std::find_if(std::begin(V), std::end(V), [&Name](const auto &v){return (Name == v.name);});
        
            std::cout<< "found at: V["<<std::distance(std::begin(V),found)<<"]" <<std::endl;
        }
        

        结果是:

        found at: V[2]
        

        示例:https://rextester.com/IYNA58046

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-08-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多