2015-05-14 27 views
3

問題: C++ 11對複數進行了一些更改,因此real()imag()不能再像成員變量一樣被使用和濫用。 我有一些代碼,我轉換通過real()imag()sincosf()作爲參考。它看起來有點像這樣:通過引用傳遞複雜的真實和圖形

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

現在,這給出了一個error: lvalue required as unary '&' operand

其誤差不前,C++ 11接收。

我的問題:是否有一個簡單的行內修復?還是必須創建臨時變量才能獲得結果,然後通過setter將它們傳遞給複數?

謝謝

+3

嗯...從C++ 03標準[lib.complex]'T真實()const的; T imag()const;',所以這些函數永遠不會返回左值。無論是舊的stdlib實現還是舊的編譯器都不符合要求。 – Praetorian

+0

我在98 ...我們有點遠遠 – Cory

+2

你可以使用'reinterpret_cast'來獲得指向實部和虛部的指針。 'std :: complex'是我知道標準實際保證這個工作的一種情況。 –

回答

2

只要做

cplx = std::polar(1.0f, /*...*/); 
+0

'polar'是真實的cos,虛擬的sin,這是與問題相反的部分(實部sin,虛部cos)。 –

+0

@ T.C。 'std :: polar(1.0f,pi/2 - /*...*/);'然後。雖然我懷疑OP實際上只是想要「極地」。 –

3

正如T.C. mentions在評論中,該標準允許您以reinterpret_caststd::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]); 
+0

雖然這是一個更直接的答案,yuri's提供了一個更清晰的結果。 – Cory

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