Почему сложный <double>* int не определен в C ++? - PullRequest
10 голосов
/ 29 октября 2009

Программа на C ++

#include <complex>
#include <iostream>

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

выдает ошибку: нет совпадения для «оператора *» в «z * n». Зачем?

Я компилирую с g ++ 4.4.1. Возможно, компилятор просто следует стандарту C ++, и в этом случае мой вопрос таков: почему стандарт не позволяет этого?

Ответы [ 2 ]

14 голосов
/ 29 октября 2009

Это работает:

#include <complex>
#include <iostream>

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

Поскольку комплекс состоит из двойников, он умножается на двойники. Глядя на декларацию:

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

(благодаря dribeas ) компилятору не разрешено делать неявные преобразования типов во время вывода шаблона, поэтому, передавая complex с T , являющимся double и затем другой T , являющийся int, при попытке сопоставить функцию, трактующую T как double, приводит к несовпадению второго аргумента, и наоборот.

Для того, что вы хотите работать, должна быть определена функция, подобная этой:

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

Что позволяет функции принимать разные типы, что позволяет выполнять приведение при вызове operator*=.

2 голосов
/ 29 октября 2009

std::complex<T> операторы определены, чтобы принимать в качестве аргументов другие complex<T> экземпляры.Маршрут от int через double к complex<double> слишком незначительно искажен / запутан для того, чтобы язык C ++ следовал ему в соответствии со стандартом (и с огромными сложностями, уже возникающими из-за свободных преобразований и согласований).Трудно критиковать этот аспект стандарта).Я полагаю, что сверхспециальный случай complex<double>, позволяющий опущенные int s в качестве операндов своим операторам, просто не считался частым и достаточно важным, чтобы оправдать указание специализаций шаблонов для этого чрезвычайно индивидуального случая, учитывая, насколько это легко для программиста.бросить int в double, когда они на самом деле хотят ! -)

...