How to overload% operator for template class?

I created a template class number. I'm overloaded with the <operator, but I can't seem to get the% operator to work.

template<typename t>
class Number
{
private:
    t n;
public:
    Number(t a) :n{ a } {};
    Number() :n{ t() } {};
    friend ostream & operator<<<>(ostream & os, const Number<t>& a);
    friend Number<t> operator%(Number<t> a, Number<t> b);
};
template<typename t>
ostream & operator<<<>(ostream & os, Number<t> a)
{
    os << a.n;
    return os;
}
template<typename t> 
Number<t> operator%(Number<t> a, Number<t> b)
{
    return Number<t>(a.n % b.n);
}

      

As you can see the <> in <operator that does the job. But if I use this in the definition of the% operator, I get a syntax error, and if I don't get "1 unresolved external" error. So my problem can be summed up in two questions: 1. Why do we need to use <> when overloading an operator using friends notation? 2. Why doesn't it work for% operator?

+3


source to share


4 answers


Method 1

Declare functions before defining the class template.

template <typename t> class Number;

template <typename t>
std::ostream & operator<<(std::ostream & os, const Number<t>& a);

template <typename t>
Number<t> operator%(Number<t> a, Number<t> b);

      

Define a class. Make sure your ads friend

use a template parameter.

template <typename t>
class Number
{
private:
    t n;
public:
    Number(t a) :n{ a } {};
    Number() :n{ t() } {};

    // This makes sure that operator<< <int> is a friend of Number<int>
    // but not of Number<double>
    friend std::ostream & operator<< <t>(std::ostream & os, const Number& a);
    friend Number operator%<t>(Number a, Number b);
};

      

Implement functions outside of the class definition.

template <typename t>
std::ostream & operator<<(std::ostream & os, const Number<t>& a)
{
    os << a.n;
    return os;
}

template <typename t> 
Number<t> operator%(Number<t> a, Number<t> b)
{
    return Number(a.n % b.n);
}

      



Working code http://ideone.com/dx3fC0 .

Method 2

Inject functions friend

inside a class template definition.

template <typename t>
class Number
{
   private:
      t n;
   public:
      Number(t a) :n{ a } {};
      Number() :n{ t() } {};
      friend std::ostream& operator<<(std::ostream & os, const Number& a)
      {
         os << a.n;
         return os;
      }

      friend Number operator%(Number a, Number b)
      {
         return Number<t>(a.n % b.n);
      }
};

      

Working code http://ideone.com/5PYQnR .


If the functions are friend

not too complex, the second method is better. The general structure of the code is simple. If the functions friend

are complex, it might make sense to use the first method and implement them outside of the class definition.

+4


source


You must first declare the operator as a function template before befriending it in the class. See this and for more details on how to do this correctly.

The reason you left off operator <<

, as I suspect, is using namespace std

not being displayed in your question, which contributes to the templated ad operator <<

from <iostream>

.



This should work:

#include <iostream>

template<typename T>
class Number;

// Declare the operators here.
template<typename T>
std::ostream & operator<<(std::ostream & os, const Number<T>& a);

template<typename T>
Number<T> operator%(Number<T> a, Number<T> b);

template<typename T>
class Number
{
private:
    T n;
public:
    Number(T a) :n{ a } {};
    Number() :n{ T() } {};

    friend std::ostream & operator<< <T>(std::ostream & os, const Number& a);

    friend Number operator% <T>(Number a, Number b);
};

template<typename T>
std::ostream & operator<<(std::ostream & os, const Number<T>& a /* was Number<T> ==> signature mismatch */) 
{
    os << a.n;
    return os;
}

template<typename T> 
Number<T> operator%(Number<T> a, Number<T> b)
{
    return Number<T>(a.n % b.n);
}

int main() {
    Number<int> a(5);
    Number<int> b(6);
    auto c = a % b;
    std::cout << a << std::endl;
    return 0;
}

      

+1


source


Define these functions in the class body and save yourself the hassle. Also, in case the left operand %

is equal Number

, you don't need to make it a friend.

#include <iostream>

using std::ostream;

template<typename t>
class Number
{
private:
    t n;
public:
    Number(t a) :n{ a } {};
    Number() :n{ t() } {};

    Number operator%(Number rhs)
    {
        return Number(n % rhs.n);
    }

    friend ostream & operator<<(ostream & os, Number a)
    {
       os << a.n;
       return os;
    }
};


int main()
{
  Number<int> n1(4);
  Number<int> n2(2);

  std::cout << n1 << ' ' << n2 << '\n';

  Number<int> n3 = n1 % n2;
  std::cout << n3 << '\n';
}

      

0


source


You can make the template operator itself a friend:

template<typename t>
class Number
{
private:
    t n;
public:
    Number(t a) :n ( a ){};
    Number() :n( t() ) {};

    template<typename TT>
    friend Number<TT> operator%(Number<TT> a,const Number<TT>& b);
};

template<typename t> 
Number<t> operator%(Number<t> a,const Number<t> &b)
{
    return Number<t>(a.n % b.n);
}


int _tmain(int argc, _TCHAR* argv[])
{
    Number<int> a;
    Number<int> b;

    Number<int> c = a %b;
    return 0;
}

      

See an explanation about declaring an extrovert here .

0


source







All Articles