C++ 哪个lambda有更多的机会内联

C++ 哪个lambda有更多的机会内联,c++,c++14,C++,C++14,在我看来,如果lambda必须存储state,它很可能不会内联。如果它不存储状态,那么它就像一个简单的自由函数,并且有更多的机会是内联的 标准对此有什么说明吗 class Window {public:int value = 5;}; class SomeClass: { public: Window *w; void DoSomething() { auto error = [&](int n) {

在我看来,如果lambda必须存储state,它很可能不会内联。如果它不存储状态,那么它就像一个简单的自由函数,并且有更多的机会是内联的

标准对此有什么说明吗

class Window {public:int value = 5;};

class SomeClass:
{
public:
    Window *w;

    void DoSomething()
    {
         auto error = [&](int n)
         {
             std::cout << (w->value  * 5);
             return w->value * n;
         };

         auto error  = [](Window *w, int n)
         {
             std::cout << (w->value  * 5);
             return w->value * n;
         };

         error(w, 7);
         error(7);
         // ...

         error(w, 10);
         error(10);

    }
}
类窗口{public:int-value=5;};
类SomeClass:
{
公众:
窗口*w;
无效剂量测定法()
{
自动错误=[&](整数n)
{
std::cout值*5);
返回w->value*n;
};
自动错误=[](窗口*w,整数n)
{
std::cout值*5);
返回w->value*n;
};
误差(w,7);
错误(7);
// ...
误差(w,10);
错误(10);
}
}

作为一个在过去几年中花了我大部分业余时间编写编译器以在LLVM之上运行的人,我非常确定任何一个好的编译器都会将这两个编译器都内联起来——如果不是,我会向任何一个没有内联编译器的人提出一个bug

[…]
中的内容只是一个额外的参数(“闭包参数”),它通常会变成指向结构的指针[当函数内联时/如果函数内联时,可以将其“取消勾选”为常规参数]

一个简单的小函数没有内联的主要原因是它是通过函数指针(包括vtable)调用的。非内联版本中也可能生成非静态[全局级别]函数,因为编译器无法确定该函数未在其他地方调用

当然,大型函数可能不会内联,因为编译器认为这样做是浪费空间,但例如,gcc将内联非常大的函数,因为已知这些函数只能从一个位置调用

我还认为,编译器将lambda内联到其他函数的方式没有区别——可能除了这样一个事实,即它们显然不能从其他任何地方调用(除非lambda从声明为std::function或类似函数的函数中传递出去,但它不能以任何方式内联)


如果你真的在意,那就检查一下编译器的输出。

@CaptainObvlious我问过标准有没有提到它。据我所知,该标准并不依赖于不同的编译器。如果您的编译器内联也有问题,请提交一个bug。虽然我承认不知道该标准对此有何规定,但这里有两个不同的东西:lambda函数,无论出于何种目的,它都可以独立于lambda所携带的状态以及与函数分开存储的状态进行内联。因此,唯一的事情应该是选择内联,这是与函数本身,和通常的考虑(函数大小,呼叫者的数量)申请。@玉米秸秆:C++不真正承认内联的可能性。
inline
关键字实际上更像是一个链接器指令,而不是其他任何东西。不过,我应该更正我的原始注释,因为结果表明闭包的函数运算符声明为
inline
(参见第5.1.2节第5段)。但也就是说,标准并没有说其中一个比另一个更有可能被内联。我花了30分钟试图找出这个问题。这个问题使得我的lambda body函数太长,无法在发布模式下内联。对这种行为有什么看法吗?或者我应该报告的只是一个visual studio bug?
va_arg
函数不能内联。虽然规范可能没有这样说,但我还没有看到一个编译器来处理这个问题。这是因为参数数量可变,参数在堆栈上传递[在典型情况下],通常不可能内联正确的堆栈清理。(我撒谎-我见过我们的OpenCL编译器在内联printf中工作-但这无论如何都不是一件好事,因为这意味着编译时间会增长到“很长”在同一段代码中调用printf十几次,因为多次内联~3000行printf对编译器性能不是特别好),但printf有一个主体。我的没有(它总是返回相同的值,并且不使用参数)我认为编译器应该足够聪明,不会生成任何代码。它仍然需要获取任意数量的参数,而且显然编译器不会费心检查它是否从未被调用,从而将其删除[或者它依赖链接器删除死函数]