10

C++プログラム

#include <complex>
#include <iostream>

int main()
{
  std::complex<double> z(0,2);
  int n = 3;
  std::cout << z * n << std::endl;
}

エラーが発生します:「z*n」の「operator*」に一致しません。なんで?

私はg++4.4.1でコンパイルしています。おそらく、コンパイラはC ++標準に準拠しているだけです。その場合、私の質問は次のとおりです。標準でこれが許可されないのはなぜですか。

4

2 に答える 2

15

これは機能します:

#include <complex>
#include <iostream>

int main()
{
    std::complex<double> z(0,2);
    double n = 3.0; // Note, double
    std::cout << z * n << std::endl;
}

複合体はdoubleで構成されているため、doubleで乗算されます。宣言を見てください:

template <typename T>
inline complex<T> operator*(const complex<T>&, const T&);

(以下はdribeasのおかげです)コンパイラはテンプレートの推論中に暗黙の型変換を行うことを許可されていないため、Tを次のように扱う関数と一致させようとすると、complexTdouble、次に別のTがが渡されます。不一致、およびその逆。intdouble

作業したいものについては、次のように定義された関数が必要になります。

template <typename T, typename U>
inline std::complex<T> operator*(std::complex<T> lhs, const U& rhs)
{
    return lhs *= rhs;
}

これにより、関数はさまざまな型をとることができ、を呼び出すときにキャストを実行できますoperator*=

于 2009-10-29T05:56:02.017 に答える
2

std::complex<T>の演算子は、他のcomplex<T>インスタンスを引数として取るように定義されています。intviaからadoubleへのルートはcomplex<double>、C ++言語が標準に従ってそれに従うには、わずかにゆがんで/複雑すぎます(そして、自由奔放な変換とコヒージョンからすでに生じている巨大な複雑さで、標準のその側面を批判するのは難しいです)。complex<double>キャストされていないsを演算子のオペランドとして許可するという非常に特殊なケースは、プログラマーがそのときにキャストするintのがいかに簡単であるかを考えると、その非常に個別のケースにテンプレートの特殊化を指定することを保証するほど頻繁で重要であるとは見なされていなかったと思います。彼らが実際に望んでいること!-)intdouble

于 2009-10-29T06:03:11.427 に答える