通过引用传递复杂的真实和图像

时间:2015-05-14 18:48:18

标签: c++ c++11 reference complex-numbers rvalue

问题: C ++ 11对复数进行了一些更改,因此real()imag()不再像成员变量一样被使用和滥用。 我有一些我正在转换的代码,它通过引用将real()imag()传递给sincosf()。它看起来有点像这样:

sincosf(/*...*/, &cplx.real(), &cplx.imag());

现在提供error: lvalue required as unary '&' operand

在c ++ 11之前没有收到错误。

我的问题:是否有简单的内联修复?或者我是否必须创建临时变量以获得结果,然后通过setter将它们传递给复数?

由于

3 个答案:

答案 0 :(得分:3)

作为T.C. mentions在评论中,该标准允许您reinterpret_cast std::complex了解您的内容。

来自N3337,§26.4/ 4 [complex.numbers]

  

如果z cv std::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 cv std::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