在C++中用常数乘以复数

9
以下代码无法编译。
#include <iostream>
#include <cmath>
#include <complex>

using namespace std;

int main(void)
{
    const double b=3;
    complex <double> i(0, 1), comp;

    comp = b*i;

    comp = 3*i;

    return 0;
}

出错了:在“3 * i”中没有匹配的“operator*”。 为什么我不能与立即常量相乘? b*i可以。
3个回答

7

std::complex 类有些愚蠢...定义这些允许自动提升:

// Trick to allow type promotion below
template <typename T>
struct identity_t { typedef T type; };

/// Make working with std::complex<> nubmers suck less... allow promotion.
#define COMPLEX_OPS(OP)                                                 \
  template <typename _Tp>                                               \
  std::complex<_Tp>                                                     \
  operator OP(std::complex<_Tp> lhs, const typename identity_t<_Tp>::type & rhs) \
  {                                                                     \
    return lhs OP rhs;                                                  \
  }                                                                     \
  template <typename _Tp>                                               \
  std::complex<_Tp>                                                     \
  operator OP(const typename identity_t<_Tp>::type & lhs, const std::complex<_Tp> & rhs) \
  {                                                                     \
    return lhs OP rhs;                                                  \
  }
COMPLEX_OPS(+)
COMPLEX_OPS(-)
COMPLEX_OPS(*)
COMPLEX_OPS(/)
#undef COMPLEX_OPS

太棒了,这比写一堆运算符要好得多。 - Santi Peñate-Vera
1
为什么 std 默认没有这个功能呢?是因为同时使用 complex<float>、complex<int>、complex<double> 和 complex<long double> 等复杂类型会过于复杂,难以概括吗?或者即使只使用 complex<double>,也存在陷阱吗? - Arnaud
不再了,复杂的类早在早期的C++中就存在了,所以可能当时使用的任何推理现在都不再适用了(如果你非常想知道,可能可以找到一些原始的讨论),但是没关系 - 没有必要束手无策,我们只能接受它们现在的状态。 - tesch1
这太不可思议了。 - orlandini

7
在第一行中:
comp = b*i;

编译器调用:
template<class T> complex<T> operator*(const T& val, const complex<T>& rhs);

这个实例是这样的:

template<> complex<double> operator*(const double& val, const complex<double>& rhs);

在第二种情况下,没有适当的模板int,因此实例化失败:
comp = 3.0 * i; // no operator*(int, complex<double>)

4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接