Назначение копирования С++ 11 для std::complex в g++ 4.5 - не соответствует оператору +

Приведенный ниже код не скомпилируется с помощью g++ версии 4.5.0 с использованием переключателя -std=c++0x. Я получаю следующее сообщение об ошибке:

error: no match for 'operator+' in 'std::pow [with _Tp = float, _Up = int, typename __gnu_cxx::__promote_2<_Tp, _Up>::__type = double](((const std::complex<float>&)((const std::complex<float>*)(& x))), ((const int&)((const int*)(&2)))) + y'

Я полагаю, что это связано с требованием Assignable, упомянутым здесь< /а>. Должен ли я определить свой собственный оператор присваивания копии для сложного? Если да, то как?

#include <complex>
using namespace std;

int main(int argc, char *argv[]) {
  complex<float> x,y;
  x = pow(x,2);      // ok
  x = x        + y;  // ok
  x = pow(x,2) + y;  // error
  return 0;
}

person user2023370    schedule 12.12.2011    source источник
comment
Упрощенная ошибка гласит: «Нет оператора +, который принимает сложный «двойной» и сложный «плавающий»».   -  person Cubbi    schedule 12.12.2011
comment
@parapura rajkumar: К сожалению, нет.   -  person user2023370    schedule 12.12.2011
comment
Это компилируется на VS2010, возможно, нужен шаблон или ключевое слово typename.   -  person AJG85    schedule 12.12.2011
comment
Помогает ли смена 2 на 2.0f?   -  person parapura rajkumar    schedule 12.12.2011
comment
Это работает, если вы используете 2.0f или если вы используете complex<double>. Я не уверен, откуда gcc получает double, возможно, это ошибка.   -  person interjay    schedule 12.12.2011


Ответы (1)


[cmplx.over]/p3 указывает дополнительные перегрузки для pow, когда задействован complex:

Шаблон функции pow должен иметь дополнительные перегрузки, достаточные для обеспечения при вызове хотя бы с одним аргументом типа complex<T>:

  1. Если какой-либо из аргументов имеет тип complex<long double> или тип long double, то оба аргумента фактически преобразуются в complex<long double>.

  2. В противном случае, если какой-либо из аргументов имеет тип complex<double>, double или целочисленный тип, то оба аргумента фактически преобразуются в complex<double>.

  3. В противном случае, если какой-либо из аргументов имеет тип complex<float> или float, то оба аргумента эффективно преобразуются в complex<float>.

2 преобразуется в двойное, а pow(complex<float>, double) возвращает complex<double>.

person Howard Hinnant    schedule 12.12.2011
comment
Дополнительная информация: отличие от C++03 можно проследить до этого отчета о дефекте: open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#844 — убрали дополнительную перегрузку: template‹class T› complex‹T› pow(const комплекс‹T›& x, int y); - person wolfgang; 12.12.2011
comment
Ясно спасибо. В C++03 тот же pow(x,2) возвращал complex<float> вместо complex<double>; и никогда не было operator+ между complex<float> и complex<double>. - person user2023370; 13.12.2011