2016-09-15 2 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を掛けてください。

次のコードは、問題がvalarrayのみテンプレートタイプ上に定義されoperator*()(および類似のオペレータ)とテンプレートクラスであるということである

#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}; 
} 

をコンパイル。

std::valarray<double>doubleスカラーで乗算することができますので、std::valarray<std::complex<double>>std::complex<double>スカラーで乗算することができますが、std::valarray<std::complex<double>>doubleスカラーで乗算することはできません。

+0

私はこれを試したことができましたが、2番目と3番目の値はランダムでした。私の限られた範囲では、これは許容される妥協点です。 –

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>にキャストします。

関連する問題