为什么在C ++中将更大函数内的某些函数写成lambdas?

时间:2018-05-08 09:54:32

标签: c++ c++11 lambda

我的印象是,编写一个只做一件事的清晰函数比编写一个相对较大的函数更好,这个函数不止一件事并将其作为一个lambda包围起来?

2 个答案:

答案 0 :(得分:1)

通常,特别是在标准库中的算法中,需要提供简短的功能。一些明显的例子是超短函数,它们“告诉”std::sort如何正确地比较两个值(比如说你用多个键对你自己类型的矢量进行排序,你想要排序“这次“通过其中一个键。”

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

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

答案 1 :(得分:0)

在考虑函数的长度时,考虑其中任何lambda的 body 不是长度的一部分是有用的。想象一下,他们已经被提取到其他地方并被引用。

话虽如此,让我们区分两个lambdas案例:

捕获lambda

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

E.g。给定

struct Compound
{
    int interesting_member;
    std::string uninteresting_member;
};

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

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可能更简单,而不是为执行相同任务的封闭范围添加名称。