2016-09-15 36 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>