在默认初始化器中使用“一次性”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/