2

valarray<double>スカラーで乗算できます。ただし、 a にスカラーを掛けようとするとエラーが発生しますvalarray<complex<double>>。綺麗にできる方法はないか考え中です。問題の再現は次のとおりです。

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)

テンプレートに関する私の知識は非常に限られていますが、このクラスを拡張することは可能ですか? これが私の試みです:

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

その結果Error C2039 '*': is not a member of 'std::valarray<std::complex<double>>'

コードの最初の行が機能するようにする方法v1 * 2.0や、密接な妥協をする方法はありますか?

4

2 に答える 2

3

コード 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*()

したがって、aはスカラーでstd::valarray<double>乗算できます。a はスカラーで乗算できますが、a はスカラーで乗算できません。doublestd::valarray<std::complex<double>>std::complex<double>std::valarray<std::complex<double>>double

于 2016-09-15T17:16:15.003 に答える
3

この場合の専門化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};

しかし、あなたはそれを知っていたと思います。

名前付き演算子を使用して、次を取得できます。

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

合法的に働くこと。

独自のリテラルから複素数へのコンバーターを作成することもできます。

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

実例

しかし、実際には、 にキャストしcomplex<double>ます。

于 2016-09-15T17:23:25.060 に答える