如何解决 ISO C++ 中的歧义运算符

发布于 2024-10-29 01:18:24 字数 3676 浏览 4 评论 0原文

我现在几乎没有办法将大量旧的 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 类进行了去模板化,从而得到了上面的定义。它使用 MS Visual C++ .NET 2002 在 MSC 环境中编译,没有错误和警告,但现在使用 g++ 4.2.1 时出现这些歧义错误。

我已经很久没有在 C++ 中使用重载运算符编写代码了,并且我尝试了很多重写 * 运算符的两个定义。主要问题是我不明白为什么这是不明确的。对于:

qSt * dVal

complex_d 必须与 double 变量值相乘,并且结果必须作为complex_d 返回。因此必须评估友元运算符*。当我用 替换运算符时,

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

complex_d operator*(double rhs);

收到另一个错误,告诉我需要类成员或枚举作为参数。也不可能省略所讨论的第二个运算符,因为代码中的其他位置也需要它。

有谁能告诉我如何摆脱这个困境吗?

I'm pretty much out of ideas now with porting a big bunch of old C++ code from MS Visual C++ 7.0 to iOS 4 iPhone g++ 4.2.1 compiler. I get some ambiquity errors compiling this:

complex_d*  cp;
complex_d   qSt;
double      zi;

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

with the class definition of complex_d as:

#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);
};

The two operators in question are marked as ambigous but I don't see why. Originally this class was written as a template which in fact only was instantiated with double type. So I de-templated the complex_d class which results in the definition above. It compiled w/out errors and warnings in MSC environment using MS Visual C++ .NET 2002 but I get these ambiguity errors with g++ 4.2.1 now.

I'm quite long off writing code with overloading operators in C++ and I experimented a lot rewriting the two definitions of the * operators. The main problem is I don't understand why this is ambiguous. For:

qSt * dVal

a complex_d has to be multiplied with a double variable value and the result has to be returned as complex_d. Therefore the friend operator * has to be evaluated. When I replace the operator

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

with

complex_d operator*(double rhs);

I get another error telling me that a class member or enum is needed as parameter. It is also not possible to omit the second operator in question because it is also needed at another place in the code.

Is anyone out there who can tell me how to get out of this dilemma?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

总以为 2024-11-05 01:18:24

我看到有两种方法可以解决这个问题(可能还有更多):

  1. 向构造函数添加显式内容:

    显式的complex_d(double re = 0, double im = 0);

  2. 删除友元运算符*()。

C++ std::lib 采用 std::complex 的解决方案#2。

I see two ways to fix this (there's probably more):

  1. Add explicit to the constructor:

    explicit complex_d(double re = 0, double im = 0);

  2. Remove the friend operator*().

The C++ std::lib went with solution #2 for std::complex.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文