问题: c 11已对复数进行了一些更改,以便无法再使用real()
和imag()
,例如成员变量。我有一些我正在转换的代码,该代码将real()
和imag()
通过参考将其传递给sincosf()
。看起来有点像这样:
sincosf(/*...*/, &cplx.real(), &cplx.imag());
现在给出一个error: lvalue required as unary '&' operand
在C 11之前未收到哪些错误。
我的问题:是否有简单的内联修复?还是我必须创建临时变量才能获取结果,然后通过setters将这些变量传递给复杂数字?
谢谢
作为T.C.在评论中提到,标准允许您 reinterpret_cast
std::complex
满足您内心的内容。
来自N3337,§26.4/4 [complex.numbers]
如果
z
是 cvstd::complex<T>
类型的lvalue表达式:
&mdash;reinterpret_cast<cv T(&)[2]>(z)
表达式应构成良好,
&mdash;reinterpret_cast<cv T(&)[2]>(z)[0]
应指定z
的实际部分,
&mdash;reinterpret_cast<cv T(&)[2]>(z)[1]
应指定z
的虚构部分。
此外,如果a
是类型 cvstd::complex<T>*
的表达式,并且表达式a[i]
对于整数表达式i
已很好地定义,则:
&mdash;reinterpret_cast<cv T*>(a)[2*i]
应指定a[i]
的实际部分,
&mdash;reinterpret_cast<cv T*>(a)[2*i + 1]
应指定a[i]
的虚构部分。
因此,在代码中进行以下替换
sincosf(/*...*/,
&reinterpret_cast<T*>(&cplx)[0],
&reinterpret_cast<T*>(&cplx)[1]);
只是做
cplx = std::polar(1.0f, /*...*/);
不要以为良好的优化编译器(例如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