Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“lambda很便宜”-真的吗?在什么情况下? 本文声明使用C++ LAMBDAS是便宜的: _C++_Lambda_C++14 - Fatal编程技术网

“lambda很便宜”-真的吗?在什么情况下? 本文声明使用C++ LAMBDAS是便宜的:

“lambda很便宜”-真的吗?在什么情况下? 本文声明使用C++ LAMBDAS是便宜的: ,c++,lambda,c++14,C++,Lambda,C++14,它们演示了如何将lambda传递给现有的std函数/模板。 一篇文章演示了如何使用auto作为函数的返回类型来返回lambda,而不使用std::function 我没有看到一篇文章演示如何在不使用std::function的情况下创建自己的函数,特别是类成员函数,这些函数使用lambda或更多 因此,这种大胆的lambda声明是廉价的——在现实世界中,这真的是真的吗 作为参考:便宜对我来说是解决这一问题的特别途径:在具有数百千字节内存和两位数MHz速度的嵌入式裸机项目上可以合理地使用。我一直在

它们演示了如何将lambda传递给现有的std函数/模板。 一篇文章演示了如何使用auto作为函数的返回类型来返回lambda,而不使用std::function

我没有看到一篇文章演示如何在不使用std::function的情况下创建自己的函数,特别是类成员函数,这些函数使用lambda或更多

因此,这种大胆的lambda声明是廉价的——在现实世界中,这真的是真的吗

作为参考:便宜对我来说是解决这一问题的特别途径:在具有数百千字节内存和两位数MHz速度的嵌入式裸机项目上可以合理地使用。我一直在使用C++中的一个明智子集,并且在寻找其他我可以使用的< /P> 据我所见,std::function并不便宜。首先,作为std::函数传递的Lambdas显然不能再进行内联优化。 但更糟糕的是,std::函数有32个字节大。 同样明显的是,如果捕获到的数据超过了适合的数据,那么是否可以使用动态分配? 这听起来像是坏消息

因此,当我在寻找不使用std::function的情况下使用lambdas的方法时,只发现了一个返回auto的示例,我尝试了以下方法: 我制作了一个非常简单的类,它在成员函数中使用auto作为参数类型,编译器似乎对此很满意,尽管对于预期的函子参数,它不像std::function那样具有自文档化的代码

struct FuncyClass
{   unsigned func(auto fnx)
    {   return 2 * fnx(7);
    }
};

int main()
{   FuncyClass fc;
    auto result = fc.func( [](auto x){return x*3;} );
    
    printf("Result: %u\n", result);
    return 0;
}
// Output: "Result: 42"
但我有一种感觉,这个非常简单的场景并没有向我展示当更复杂的场景使用它时可能出现的编译器错误洪水。 我不太了解这种语法背后的情况,编译器在使用functor确定需要哪些参数和返回类型时做了什么,以及这个带有自动参数的函数是如何在后台实现的

使用自动类型的参数真的是使类成员函数lambda可定制的合理方法吗? 然后它看起来很便宜,在我的测试中,当使用auto而不是std::function时,可执行文件要小得多

当然,它仍然处于极限状态: 如果不使用std::function或类似的DIY包装器,类就无法保存lambda,对吗?
是否有可能防止动态分配发生,例如,当出现需要std::function分配内存的场景时,将其作为编译时错误?

lambda只是重载运算符的对象。您可以在概念上将其视为等同于:

class Lamba {
public:
    auto operator()(...) const { /* ... */ }
};
因此,它们并不比类似的函数调用更昂贵。std::函数不是使用lambdas所必需的。您可以使用类型推断来存储/传递它们:

template <typename Func>
void foo(Func&& func) { /* ... */ }

你的问题很难回答的原因是你在问Lambda是否贵。但是,与什么相比呢?如果您想知道它们在您的特定情况下是否有足够的性能,您必须自己做一些分析并找出答案。

lambda只是重载操作符的对象。您可以在概念上将其视为等同于:

class Lamba {
public:
    auto operator()(...) const { /* ... */ }
};
因此,它们并不比类似的函数调用更昂贵。std::函数不是使用lambdas所必需的。您可以使用类型推断来存储/传递它们:

template <typename Func>
void foo(Func&& func) { /* ... */ }
你的问题很难回答的原因是你在问Lambda是否贵。但是,与什么相比呢?如果您想知道它们在您的特定情况下是否有足够的性能,您必须自己做一些分析并找出答案。

std::function很好,因为它的语法简单,比函数指针简单得多,而且它可以自文档化与模板相比需要什么类型的函数,需要明确的文档。我想关于lambdas的介绍性文章会用到它,因为在您有一定限制之前,成本是不可见的

接受lambda作为参数还有两种方法:函数指针和模板

非捕获lambda可以隐式转换为函数指针:

struct FuncyClass
{   unsigned func(int(*fnx)(int)) 
    {   return 2 * fnx(7);
    }
};

int main()
{   FuncyClass fc;
    auto result = fc.func( [](auto x){return x*3;} );
    
    printf("Result: %u\n", result);
    return 0;
}
可借助模板传递捕获和非捕获lambda:

struct FuncyClass
{   
    template<typename Func>
    unsigned func(Func&& fnx)
    {   return 2 * fnx(7);
    }
};

int main()
{   FuncyClass fc;
    int multiplier = 3;
    auto result = fc.func( [multiplier](auto x){return x*multiplier;} );
    
    printf("Result: %u\n", result);
    return 0;
}
函数很好,因为它的语法很简单,比函数指针简单得多,并且与需要显式文档的模板相比,它可以自行记录所需的函数类型。我想关于lambdas的介绍性文章会用到它,因为在您有一定限制之前,成本是不可见的

接受lambda作为参数还有两种方法:函数指针和模板

非捕获lambda可以隐式转换为函数指针:

struct FuncyClass
{   unsigned func(int(*fnx)(int)) 
    {   return 2 * fnx(7);
    }
};

int main()
{   FuncyClass fc;
    auto result = fc.func( [](auto x){return x*3;} );
    
    printf("Result: %u\n", result);
    return 0;
}
可借助模板传递捕获和非捕获lambda:

struct FuncyClass
{   
    template<typename Func>
    unsigned func(Func&& fnx)
    {   return 2 * fnx(7);
    }
};

int main()
{   FuncyClass fc;
    int multiplier = 3;
    auto result = fc.func( [multiplier](auto x){return x*multiplier;} );
    
    printf("Result: %u\n", result);
    return 0;
}
“lambda很便宜”

这是一个相对的概念

在实践中,这取决于你的C++ COMP。 伊勒。

尝试使用最近的2020、使用和警告和优化,因此在命令行上编译C++代码——至少用g+-Walth-Wuto-O2编译。 然后是基准测试或应用程序 在Linux上,请查看并考虑使用或当然是在调试程序后使用的。对于其他操作系统和编译器,找到一些等效的

此报告可能会建议您一个好的编译器可以做什么,有时不可以,因为。有时可能会发生lambda应用程序变为

如果你喜欢这个范例,也要考虑使用。您会发现,在实践中,可以比C/C++或C++特别是Linux上的单线程程序稍微快一些。

作为经验法则,我倾向于相信C++ LAMBDA在其身体做一些重要工作时,比如在一些迭代或搜索中是便宜的。如果lambda主体只是进行一个整数加法,那么开销将非常大,除非编译器足够聪明,能够内联它。如果它在一个包含数千个条目的std::map上执行一些操作,或者实际上使用动态分配,因此一些新的、通常使用malloc的操作通常是不重要的

实际上,您需要从YMMV开始分析您的应用程序

“lambda很便宜”

这是一个相对的概念

在实践中,这很大程度上取决于C++编译器。

尝试使用最近的2020、使用和警告和优化,因此在命令行上编译C++代码——至少用g+-Walth-Wuto-O2编译。 然后是基准测试或应用程序 在Linux上,请查看并考虑使用或当然是在调试程序后使用的。对于其他操作系统和编译器,找到一些等效的

此报告可能会建议您一个好的编译器可以做什么,有时不可以,因为。有时可能会发生lambda应用程序变为

如果你喜欢这个范例,也要考虑使用。您会发现,在实践中,可以比C/C++或C++特别是Linux上的单线程程序稍微快一些。

作为经验法则,我倾向于相信C++ LAMBDA在其身体做一些重要工作时,比如在一些迭代或搜索中是便宜的。如果lambda主体只是进行一个整数加法,那么开销将非常大,除非编译器足够聪明,能够内联它。如果它在一个包含数千个条目的std::map上执行一些操作,或者实际上使用动态分配,因此一些新的、通常使用malloc的操作通常是不重要的


实际上,您需要分析您的应用程序,因为YMMV。

Lambda本身很便宜。std::函数不是,但您不需要使用它。非捕获lambda可以转换为函数指针,捕获lambda可以作为模板传递。std::function由于使用类型擦除,所以成本很高。lambda只是一个简单的函子,相比之下,它们是便宜的。您可以将类设置为模板,并为其指定lambda的类型,以避免使用std::function。不需要使用std::function-是的,但不幸的是,在我读到的大约10篇文章/博客文章中显示了这种方法——因此我的印象是,这是一种在您自己的类中有效使用lambdas的方法。几乎所有采用函数/函子参数的标准库函数,如std::sort等,都是在不使用std::function的情况下使用的。他们使用模板,这是一种折衷。如果您知道类型,可能会发生很多优化,但这会使代码更加复杂,因为您必须处理类型。如果使用无类型的std::function,那么代码就更容易使用,但要付出性能代价。Lambda本身很便宜。std::函数不是,但您不需要使用它。非捕获lambda可以转换为函数指针,捕获lambda可以作为模板传递。std::function由于使用类型擦除,所以成本很高。lambda只是一个简单的函子,相比之下,它们是便宜的。您可以将类设置为模板,并为其指定lambda的类型,以避免使用std::function。不需要使用std::function-是的,但不幸的是,在我读到的大约10篇文章/博客文章中显示了这种方法——因此我的印象是,这是一种在您自己的类中有效使用lambdas的方法。几乎所有采用函数/函子参数的标准库函数,如std::sort等,都是在不使用std::function的情况下使用的。他们使用模板,这是一种折衷。如果您知道类型,可能会发生很多优化,但这会使代码更加复杂,因为您必须处理类型。如果您使用无类型的std::function,那么代码更容易使用,但您会付出性能代价。据说可以作为模板传递,但实际上您不会将任何内容传递给模板定义,让编译器从lamda推断替换。这可能会令人困惑,据说可以作为模板传递,但实际上并没有将任何内容传递给模板定义,leavin
g编译器从lamda推断替换。考虑到最初的印象,STD::函数几乎不可能与LAMBDAS结合使用,这是令人困惑的,我估计大多数人认为动态分配可以不便宜地发生,它对我来说似乎并不那么模糊。基本上是的,这确实是一个廉价的证据,我希望能证明在没有std::函数的情况下使用lambdas既可行又实用——我希望我的帖子中能表达这种观点。@sktpin:如果你的问题真的是关于你是否可以使用lambdas而不必在std::函数或类似的基于分配的操作中捕获它们,然后,也许你应该相应地调整你的标题和问题文本,而不是使用关于什么东西便宜之类的问题。这个问题背后的动机是我想知道lambdas是否可以便宜地实际使用。某种看起来会妨碍它的东西是std::function,因此成为焦点。不过,我对它的理解可能是错误的,而且我可能还遗漏了更多方面。因此,仅仅询问std::function可能无法提供实际决策所需的全部信息。为什么这样思考,只有亚原子水平的问题才被认为是好的?几乎可以预料到,你可以基本上回答你的问题。考虑到最初的印象,我得到了STD::函数很难与LAMBDAS结合使用,而且我估计大多数人认为动态分配可以不便宜地发生,对我来说似乎并不那么模糊。基本上是的,这确实是一个廉价的证据,我希望能证明在没有std::函数的情况下使用lambdas既可行又实用——我希望我的帖子中能表达这种观点。@sktpin:如果你的问题真的是关于你是否可以使用lambdas而不必在std::函数或类似的基于分配的操作中捕获它们,然后,也许你应该相应地调整你的标题和问题文本,而不是使用关于什么东西便宜之类的问题。这个问题背后的动机是我想知道lambdas是否可以便宜地实际使用。某种看起来会妨碍它的东西是std::function,因此成为焦点。不过,我对它的理解可能是错误的,而且我可能还遗漏了更多方面。因此,仅仅询问std::function可能无法提供实际决策所需的全部信息。为什么这样思考,只有亚原子水平的问题才被认为是好的?看起来你基本上可以自己回答你的问题。与之相比,我给出了一个粗略的参考分数。有更广泛、更实用的方法来看待事物,有些事物有时可以被归类为成本高昂的一整类场景,而不需要在纳秒内衡量它到底有多糟糕,我怀疑这可能是这样的情况。你不会坚持用零漂微伏计来测量是否需要更换电池。与之相比,我给出了一个粗略的参考标记。有更广泛、更实用的方法来看待事物,有些事物有时可以被归类为成本高昂的一整类场景,而不需要在纳秒内衡量它到底有多糟糕,我怀疑这可能是这样的情况。你不会坚持用零漂微伏计测量是否更换电池。