C++ lambda 语法
Posted
技术标签:
【中文标题】C++ lambda 语法【英文标题】:C++ lambda syntax 【发布时间】: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 主体中引用封闭函数局部变量,除非它在捕获列表中。
【问题讨论】:
Noreturn
如果没有找到?
【参考方案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->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->info.name
是有效的语法。它只是不会进行类型检查,因为向量不会重载->
。
It just won't typecheck since vectors don't overload ->
所以......它不会编译?在不重载 operator->
的类型对象上使用 ->
是一种无效语法
并非所有编译错误都是语法错误。见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(), [&Name](type& V) return Name == V->info.name;)
【讨论】:
【参考方案5】:使用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
【讨论】:
以上是关于C++ lambda 语法的主要内容,如果未能解决你的问题,请参考以下文章