问题: C ++ 11对复数进行了一些更改,因此real()
和imag()
不再像成员变量一样被使用和滥用。
我有一些我正在转换的代码,它通过引用将real()
和imag()
传递给sincosf()
。它看起来有点像这样:
sincosf(/*...*/, &cplx.real(), &cplx.imag());
现在提供error: lvalue required as unary '&' operand
在c ++ 11之前没有收到错误。
我的问题:是否有简单的内联修复?或者我是否必须创建临时变量以获得结果,然后通过setter将它们传递给复数?
由于
答案 0 :(得分:3)
作为T.C. mentions在评论中,该标准允许您reinterpret_cast
std::complex
了解您的内容。
来自N3337,§26.4/ 4 [complex.numbers]
如果
z
是 cvstd::complex<T>
类型的左值表达式,则:
- 表达式reinterpret_cast<cv T(&)[2]>(z)
应格式良好,
-reinterpret_cast<cv T(&)[2]>(z)[0]
应指定z
和/的真实部分 -reinterpret_cast<cv T(&)[2]>(z)[1]
应指定z
的虚部 此外,如果a
是 cvstd::complex<T>*
类型的表达式,并且表达式a[i]
已为整数表达式i
定义良好,则:
-reinterpret_cast<cv T*>(a)[2*i]
应指定a[i]
和/的真实部分 -reinterpret_cast<cv T*>(a)[2*i + 1]
应指定a[i]
的虚部。
因此,请在代码中进行以下替换
sincosf(/*...*/,
&reinterpret_cast<T*>(&cplx)[0],
&reinterpret_cast<T*>(&cplx)[1]);
答案 1 :(得分:2)
只做
TG_split
$OJ.0.5
[1] 15.2 21.5 17.6 9.7 14.5 10.0 8.2 9.4 16.5 9.7
$VC.0.5
[1] 4.2 11.5 7.3 5.8 6.4 10.0 11.2 11.2 5.2 7.0
$OJ.1
[1] 19.7 23.3 23.6 26.4 20.0 25.2 25.8 21.2 14.5 27.3
$VC.1
[1] 16.5 16.5 15.2 17.3 22.5 17.3 13.6 14.5 18.8 15.5
$OJ.2
[1] 25.5 26.4 22.4 24.5 24.8 30.9 26.4 27.3 29.4 23.0
$VC.2
[1] 23.6 18.5 33.9 25.5 26.4 32.5 26.7 21.5 23.3 29.5
答案 2 :(得分:0)
鉴于优秀的编译器(例如,gcc -O3
),不要宣称临时工作仍然是一个不错的选择并且应该像以前一样高效。
在此处gcc -O3
查看生成的程序集:https://goo.gl/uCPAa9
使用此代码:
#include<complex>
std::complex<float> scf1(float x) {
float r = 0., i = 0.;
sincosf(x, &r, &i);
return std::complex<float>(r, i);
}
void scf2(std::complex<float>& cmp, float x) {
float r = 0., i = 0.;
sincosf(x, &r, &i);
cmp.real(r);
cmp.imag(i);
}
void scf3(std::complex<float>& cmp, float x) {
float r = 0., i = 0.;
sincosf(x, &cmp.real(), &cmp.imag());
}
scf2
等同于你的陈述,你可以在三种情况下看到非常类似的汇编。
scf1(float):
subq $24, %rsp
leaq 8(%rsp), %rsi
leaq 12(%rsp), %rdi
call sincosf
movss 12(%rsp), %xmm0
movss %xmm0, (%rsp)
movss 8(%rsp), %xmm0
movss %xmm0, 4(%rsp)
movq (%rsp), %xmm0
addq $24, %rsp
ret
scf2(std::complex<float>&, float):
pushq %rbx
movq %rdi, %rbx
subq $16, %rsp
leaq 8(%rsp), %rsi
leaq 12(%rsp), %rdi
call sincosf
movss 12(%rsp), %xmm0
movss %xmm0, (%rbx)
movss 8(%rsp), %xmm0
movss %xmm0, 4(%rbx)
addq $16, %rsp
popq %rbx
ret
scf3(std::complex<float>&, float):
pushq %rbx
movq %rdi, %rbx
subq $16, %rsp
leaq 8(%rsp), %rsi
leaq 12(%rsp), %rdi
call sincosf
movss 12(%rsp), %xmm0
movss %xmm0, (%rbx)
movss 8(%rsp), %xmm0
movss %xmm0, 4(%rbx)
addq $16, %rsp
popq %rbx
ret