Как разрешить неоднозначный оператор в ISO C ++ - PullRequest
1 голос
/ 03 апреля 2011

У меня почти нет идей, когда я портирую большую кучу старого кода C ++ из MS Visual C ++ 7.0 на компилятор iOS 4 iPhone g ++ 4.2.1.Я получаю некоторые ошибки двусмысленности, компилируя это:

complex_d*  cp;
complex_d   qSt;
double      zi;

// complex_d += complex_d * double
*cp += qSt * dVal;  // ISO C++ says that these are ambiguous

с определением класса complex_d как:

#include <math.h>
#include "CObject.h"    // emulated MFC class, used for some types like BOOL
#include "CString.h"    // emulated MFC class, also needed for some types not on iOS

//  interface for complex calculations
//
/////////////////////////////////////////////////////////////////////////////

class polar_d;  // forward declaration

class complex_d
{
// attributes
protected:
    double  re;
    double  im;

// construction
public:
    complex_d(double re = 0, double im = 0);
    complex_d(const complex_d& x);
    virtual ~complex_d() { };

// implementation
public:
    double  real(void) const;
    double  imag(void) const;
    double& setReal(void);      // needed because we don't have Serialize() here
    double& setImag(void);      // as above

    double  Abs(void) const;
    double  Phi(void) const;

    complex_d   Conjugate(void);
    polar_d     Polar(void);

    BOOL    IsZero(void) const;
    BOOL    IsReal(void) const;
    BOOL    IsImag(void) const;

    complex_d& operator=(const complex_d& rhs);
    complex_d& operator+=(const complex_d& rhs);
    complex_d& operator-=(const complex_d& rhs);
    complex_d& operator*=(const complex_d& rhs);
    complex_d& operator/=(const complex_d& rhs);

    complex_d operator+(const complex_d& rhs);
    complex_d operator-(const complex_d& rhs);
    complex_d operator*(const complex_d& rhs);  // ambiguous error here...
    complex_d operator/(const complex_d& rhs);

    complex_d operator-(void);          // unary

    complex_d& operator=(const double& rhs);

    friend complex_d operator+(const complex_d& lhs, double rhs);
    friend complex_d operator+(double lhs, const complex_d& rhs);
    friend complex_d operator-(const complex_d& lhs, double rhs);
    friend complex_d operator-(double lhs, const complex_d& rhs);
    friend complex_d operator*(const complex_d& lhs, double rhs);   // ... and here also ambigous
    friend complex_d operator*(double lhs, const complex_d& rhs);
    friend complex_d operator/(const complex_d& lhs, double rhs);
    friend complex_d operator/(double lhs, const complex_d& rhs);
    friend BOOL operator==(const complex_d& lhs, double rhs);
    friend BOOL operator==(double lhs, const complex_d& rhs);
    friend BOOL operator!=(const complex_d& lhs, double rhs);
    friend BOOL operator!=(double lhs, const complex_d& rhs);

    friend BOOL operator==(const complex_d& lhs, const complex_d& rhs);
    friend BOOL operator!=(const complex_d& lhs, const complex_d& rhs);
};

Два рассматриваемых оператора отмечены как неоднозначные, ноЯ не понимаю почему.Первоначально этот класс был написан как шаблон, который фактически был создан только с типом double .Поэтому я удалил шаблон класса complex_d , что привело к приведенному выше определению.Он скомпилировал без ошибок и предупреждений в среде MSC, используя MS Visual C ++ .NET 2002, но теперь я получаю эти ошибки неоднозначности с g ++ 4.2.1.

Я довольно долго не пишу код с операторами перегрузки в C ++и я много экспериментировал, переписывая два определения операторов *.Основная проблема в том, что я не понимаю, почему это неоднозначно.Для:

qSt * dVal

complex_d должен быть умножен на значение двойной переменной, а результат должен быть возвращен как complex_d.Поэтому оператор друга * должен быть оценен.Когда я заменяю оператор

friend complex_d operator*(const complex_d& lhs, double rhs);

на

complex_d operator*(double rhs);

, я получаю еще одну ошибку, сообщающую, что в качестве параметра требуется член класса или перечисление.Также невозможно опустить второй рассматриваемый оператор, поскольку он также необходим в другом месте кода.

Кто-нибудь может подсказать мне, как выйти из этой дилеммы?

1 Ответ

3 голосов
/ 03 апреля 2011

Я вижу два способа исправить это (возможно, есть и другое):

  1. Добавить явное в конструктор:

    явное complex_d (double re = 0, double im= 0);

  2. Удалить оператор друга * ().

В C ++ std :: lib добавлено решение № 2 для std::. комплекс

...