为啥在 C++ 中将较大函数中的某些功能编写为 lambdas?

Posted

技术标签:

【中文标题】为啥在 C++ 中将较大函数中的某些功能编写为 lambdas?【英文标题】:Why are some functionalities inside a bigger function written as lambdas in C++?为什么在 C++ 中将较大函数中的某些功能编写为 lambdas? 【发布时间】:2018-05-08 09:54:31 【问题描述】:

我的印象是,编写只做一件事的简洁函数比编写一个相对较大的函数做多件事并将其封装为 lambda 更好?

【问题讨论】:

这纯粹是关于观点/风格。我认为这里没有太多客观的答案。 一般的建议是通过编写独立的函数来以更加模块化的方式构建代码。你在这方面是正确的。没什么可说的,这只是一个建议。 许多 2 行长的内部函数不属于公共头文件,但这是你在没有 lambda 的情况下往往会得到的。如果您的 lambda 行数超过几行,请考虑将其设为独立函数。 【参考方案1】:

很多时候,尤其是在标准库中的算法中,需要提供一个简短的函数。其中一些明显的例子是“告诉”std::sort 如何正确比较两个值的超短函数(例如,您正在使用多个键对自己类型的向量进行排序,并且您希望“这次”按其中一个键)。

在这些情况下,过去需要(C++11 之前)将该短函数编写为命名函数。这样做通常会污染名称空间,为了解决这个问题 - 引入了 lambda。

这并不违反“一个功能 - 一件事”原则,因为在这种情况下,lambda 只是一个支持就地短代码的快捷方式,否则需要将其放入独立的命名函数中。

【讨论】:

【参考方案2】:

在考虑函数的长度时,将其中的任何 lambdas 的 body 视为 not 长度的一部分是很有用的。想象一下,它们已被提取到其他地方并被引用。

话虽如此,让我们区分两种 lambda:

捕获 lambdas

实际上需要在函数中定义,因为替代方法是使用适当的operator() 和一些初始化程序创建类类型。这些函数类型的值在使用它们的函数之外并没有真正的用处。这既是更多样板,又是更少本地化,没有优势。

例如给定

struct Compound

    int interesting_member;
    std::string uninteresting_member;
;

如果您想仅根据interesting_member 的值在std::vector<Compound> 中找到特定的Compound,您也可以实现它

struct CompoundFinder

    bool operator(const Compound & item)  return item.interesting_member == needle; 
    int needle;


std::vector<Compound>::iterator find_by_interesting(int needle, std::vector<Compound> & haystack)

    return std::find_if(haystack.begin(), haystack.end(), CompoundFinder needle );

或使用捕获 lambda

std::vector<Compound>::iterator find_by_interesting(int needle, std::vector<Compound> & haystack)

    return std::find_if(haystack.begin(), haystack.end(), 
        [needle](const Compound & item) 
         return item.interesting_member == needle; );

非捕获 lambdas

这里不太清楚。如果您只需要一个特定函数一次,则定义 lambda 会比在执行相同任务的封闭范围中添加名称更简单。

【讨论】:

以上是关于为啥在 C++ 中将较大函数中的某些功能编写为 lambdas?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在VC++6.0下用C语言调用引用参数如:void Creat(SqList &L)总是提示&出错?

在 C++ 中将指针转换为数组形式的问题?

在 C++ 中将字符转换为整数

在 C++ 中将文件读入字符数组

C++ 中将默认变量类型设置为 int 的任何选项

多线程在 C++ 中的 Windows 中将多个客户端连接到单个服务器