c++ - 在默认初始化程序中使用 lambda 与使用成员函数

标签 c++ c++11 lambda data-members

在默认初始化器中使用“一次性”lambda 和使用普通的旧成员函数有什么不同吗?

struct A
{
    int i;
    int j = [&]
    // something non-trivial,
    // that requires multiple
    // statements and depends
    // on upper data members
    {
        int f = 0;
        for (int k = 0; k < i; ++k) {
            f += k;
        }
        return f;
    }();
    A(int k) : i(k) { ; }
};

对比:

struct A
{
    int i;
    int J() const
    {
        int f = 0;
        for (int k = 0; k < i; ++k) {
            f += k;
        }
        return f;
    }
    int j = J();
    A(int k) : i(k) { ; }
};

我唯一看到的是第二种方法的缺点:这里将额外的符号 J 引入到类 A 的命名空间中。还有其他区别吗?

最佳答案

关于性能,gcc 7.1 -O3 编译后的代码没有区别。两种实现都产生相同的程序集。

测试代码:

int callerFunc(int init)
{
    A st(init);
    return st.j; 
}

编译为:

callerFunc(int):
        test    edi, edi
        jle     .L7
        lea     eax, [rdi-1]
        cmp     eax, 7
        jbe     .L8
        pxor    xmm0, xmm0
        mov     edx, edi
        xor     eax, eax
        movdqa  xmm1, XMMWORD PTR .LC0[rip]
        shr     edx, 2
        movdqa  xmm2, XMMWORD PTR .LC1[rip]
.L5:
        add     eax, 1
        paddd   xmm0, xmm1
        paddd   xmm1, xmm2
        cmp     eax, edx
        jb      .L5
        movdqa  xmm1, xmm0
        mov     edx, edi
        and     edx, -4
        psrldq  xmm1, 8
        paddd   xmm0, xmm1
        movdqa  xmm1, xmm0
        cmp     edi, edx
        psrldq  xmm1, 4
        paddd   xmm0, xmm1
        movd    eax, xmm0
        je      .L10
.L3:
        lea     ecx, [rdx+1]
        add     eax, edx
        cmp     edi, ecx
        jle     .L1
        add     eax, ecx
        lea     ecx, [rdx+2]
        cmp     edi, ecx
        jle     .L1
        add     eax, ecx
        lea     ecx, [rdx+3]
        cmp     edi, ecx
        jle     .L1
        add     eax, ecx
        lea     ecx, [rdx+4]
        cmp     edi, ecx
        jle     .L1
        add     eax, ecx
        lea     ecx, [rdx+5]
        cmp     edi, ecx
        jle     .L1
        add     eax, ecx
        lea     ecx, [rdx+6]
        cmp     edi, ecx
        jle     .L1
        add     eax, ecx
        add     edx, 7
        lea     ecx, [rax+rdx]
        cmp     edi, edx
        cmovg   eax, ecx
        ret
.L7:
        xor     eax, eax
.L1:
        rep ret
.L10:
        rep ret
.L8:
        xor     eax, eax
        xor     edx, edx
        jmp     .L3
.LC0:
        .long   0
        .long   1
        .long   2
        .long   3
.LC1:
        .long   4
        .long   4
        .long   4
        .long   4

关于c++ - 在默认初始化程序中使用 lambda 与使用成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43805686/

相关文章:

c# - 编写一个接受 lambda 表达式的方法

C++ 二元运算符的优先顺序

c++ - 无法打开或找到文件 "afxwin.h",使用 .dff 进行修补(Building Doom 3 源代码)

c++ - 如果基类包含数组成员,则派生类的构造函数不能是 constexpr

c++ - VS 2008 C++ 调试 : does not show local variables for a specific function?

c++ - 编译错误,对成员变量进行多重赋值的方法,模板类 C++

c++ - 为什么常量 CLOCKS_PER_SEC 不需要命名空间为 std::但 <ctime> clock() 和 clock_t 需要?

c++ - 从 ifstream 读取不会读取空格

java - 在 Java8 中引入 lambda 会改变或影响哪种 GoF 设计模式?

c# - linq - 用非通用 Lambda 表达式替换通用 Lambda 表达式