2016-09-15 38 views
1

valarray<double>可以乘以標量。但是,如果我想要乘以valarray<complex<double>>的標量,則會出現錯誤。我想知道是否有辦法以一種漂亮的方式做到這一點。這是問題的再現:將標量乘以複數valarray

valarray<complex<double>> v1{ { complex<double>{1,0}, complex<double>{2,0}, complex<double>{3,0} } }; 
valarray<complex<double>> v2 = v1 * 2.0; // error 

生成Error C2784: 'std::complex<_Other> std::operator *(const std::complex<_Other> &,const std::complex<_Other> &)': could not deduce template argument for 'const std::complex<_Other> &' from 'std::vector<std::complex<double>,std::allocator<_Ty>>'

所以,我試圖建立自己的功能,看看它是否可以做到和下面的工作:

valarray<complex<double>> VAMult(const valarray<complex<double>> &v, double scalar) 
{ 
    valarray<complex<double>> out(v.size()); 
    for (size_t i = 0; i < v.size(); i++) 
    { 
     out[i] = v[i] * scalar; 
    } 
    return out; 
} 

// makes the following code work: 
valarray<complex<double>> v2 = VAMult(v1, 2.0); 

但這落實將使爲真正醜陋的代碼,所以我看着valarray.h,發現*超載定義:

operator*(const _Ty& _Left, 
     const valarray<_Ty>& _Right) 
{ // return scalar * valarray 
    _VALOP(_Ty, _Right.size(), _Left * _Right[_Idx]); 
} 

#define _VALOP(TYPE, LENGTH, RHS) /* assign RHS(_Idx) to new valarray */ \ 
valarray<TYPE> _Ans(LENGTH); \ 
for (size_t _Idx = 0; _Idx < _Ans.size(); ++_Idx) \ 
    _Ans[_Idx] = RHS; \ 
return (_Ans) 

我的模板方面的知識非常有限,但它可以擴展這個類?這裏是我的嘗試:導致Error C2039 '*': is not a member of 'std::valarray<std::complex<double>>'

valarray<complex<double>> valarray<complex<double>>::operator*(const double &scalar) 
{ 
    return valarray<complex<double>>{}; 
} 

有沒有辦法讓它的代碼,所以我的第一線v1 * 2.0作品或一些親密的妥協?

回答

2

有沒有辦法讓它所以我的代碼V1 * 2.0工程第一線或 一些親密的妥協?

是:將v1乘以一個複雜的標量。

以下代碼編譯

#include <complex> 
#include <valarray> 

int main() 
{ 
    std::valarray<std::complex<double>> v1{ { {1,0}, {2,0}, {3,0} } }; 
    std::valarray<std::complex<double>> v2 = v1 * std::complex<double>{2.0}; 
} 

的問題是,valarray是一個模板類與operator*()(以及類似的運營商),其僅在模板類型定義。

所以一個std::valarray<double>可以用double標量相乘,一個std::valarray<std::complex<double>>可以用std::complex<double>標量相乘但std::valarray<std::complex<double>>不能用double標量相乘。

+0

我可以發誓我試過這個,但第二個和第三個值是隨機的。鑑於我的範圍有限,這是一個可接受的折中方案。 –

2

專精operator*在這種情況下是非法的,並不會讓你得到你想要的。

重載可能,但將過載添加到namespace std是違法的。

我們可以這樣做:

valarray<complex<double>> v1{ { complex<double>{1,0}, complex<double>{2,0}, complex<double>{3,0} } }; 
valarray<complex<double>> v2 = v1 * complex<double>{2.0}; 

但我以爲你是知道的。

你可以使用named operators,並得到:

valarray<complex<double>> v2 = v1 *times* 2.0; 

合法工作。

你也可以寫自己的文字到複雜的轉換:

std::complex<double> operator"" _cplx(long double t) { 
    return {(double)std::move(t)}; 
} 

Live example

但真的,投到complex<double>