0
votes

I am trying to operator overload for a complex number, I have implemented a class where it takes in real and imaginary part. I am trying to overload the % operator where it return a modulus value(length of the real and imaginary), but I am getting error "must take exactly one argument", What am I doing wrong?

Here is my header file

complex.h

class complex{
     private:
          double rm;
          double im;
     public:
          void operator % ();

complex.cpp

void operator %(){
      complex c;
      c.re = pow(re,2);
      c.im = pow(im,2);
      return c;

Thank you!

4
% is a binary operator.molbdnilo
This is the correct signature (using inside class definition): complex operator%(const complex& other);pptaszni
double rm should be 're'kelalaka

4 Answers

3
votes

The '%' operator in C++ is a binary operator, like a % b, but you are trying to use it like a unary one. C++ allows you to overload the implementation of existing operators, but not add new ones or change how existing ones are used.

0
votes

operator% is a binary operator (some, like operator- can be unary or binary).

This means that you can define it in two different ways.

  1. As a standalone function

    complex operator%(const complex& left, const complex& right);

  2. As a class member function, in which case the 'left' term is implicitly this

    complex& complex::operator%(const complex& right);

I see a few more issues with your code. Usually in C++ % means the modulus or remainder. With complex numbers the modulus is the norm implemented in abs and it returns a real. I guess this is to make things clearer, especially when there are expressions that mix complex and real numbers. In your modulus operator you are simply squaring the real and imaginary components. I'm not sure what this is supposed to mean.

0
votes

As mentioned, the % operator is a binary operator so repurposing it as a unary modulus is not possible.

Having said that, we can abuse the free function binary operator in order to provide syntactic sugar.

Note This answer is for fun and in the spirit of learning. It is not a recommendation of a coding style.

#include <cmath>

struct imperative_mode_sentinel {};

struct complex
{
    complex(double rm, double im) : rm(rm), im(im) {}
    double rm, im;

    complex modulus() const
    {
        return complex(std::pow(rm, 2), std::pow(im, 2));
    }
};

auto operator%(imperative_mode_sentinel, complex const& r) -> complex
{
    return r.modulus();
}


constexpr static auto imperative_mode = imperative_mode_sentinel();

int main()
{
    auto c = complex(1,1);

    auto d = imperative_mode %c; // equivalent to d = c.modulus()
}
-3
votes

If this is your modulus operator, it is fine. you can give it whatever meaning you want. See;

Other than the restrictions above, the language puts no other constraints on what the overloaded operators do, or on the return type (it does not participate in overload resolution), but in general, overloaded operators are expected to behave as similar as possible to the built-in operators

class complex{
    private:
      double rm;
      double im;
    public :
          complex(int i, int r) {
              re = r; im = i;
          }
          complex operator%(const complex& mc){//for complex

                return complex(pow(re,2),pow(im,2)) ;
          }
};