C++ lambda 语法

10

我有一个函数,它搜索迭代器的向量,并在其名称与传递的字符串参数匹配时返回该迭代器。

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 表达式中的封闭函数局部变量将无法被引用。


1
如果没有找到任何内容,是否不返回“return”? - Deduplicator
5个回答

22

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

现在清楚了,您正在处理向量的一个元素,而不是整个向量本身。


8

首先,无论在 lambda 内部还是外部,V->info.name 都是不规范的。

传递给算法 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;
    }
);
< p > < code >found< /code > 的类型是指向已找到元素的迭代器。如果没有找到,则返回 < code >V.end()< /code >< /p > < p > 如果您使用C++14或更高版本,则甚至可以使用通用lambda函数:< /p >
auto found = std::find_if(
    V.begin(), V.end(), 
    [&Name](auto const& item_to_check) {
        return Name == item_to_check->info.name;
    }
);

V->info.name 是有效的语法。只是它无法通过类型检查,因为向量不支持 -> 运算符重载。 - Silvio Mayolo
3
由于向量类型不重载 ->,因此它无法通过类型检查。所以......它无法编译?对于不重载 operator-> 的对象使用 -> 是无效的语法。 - Guillaume Racicot
1
并非所有的编译错误都是语法错误。请参阅语法与语义 - Silvio Mayolo
2
@SilvioMayolo 你给我提供的答案说语义是程序的意义,通常体现在它的运行行为中。我引用的代码只是形式不正确,还没有语义。或者我对这个概念理解不正确。 - Guillaume Racicot

4

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

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

2
最初的回答:作为lambda函数的参数,将V传递进去。 std::find_if(V.begin(), V.end(), [&Name](type& V) {return Name == V->info.name;)

1
使用const auto &在lambda表达式中访问向量的单个元素。由于向量是一个左值,auto将被推导为const vector<PVertex> &。然后,您可以使用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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接