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?
source to share
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.
source to share
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;
}
source to share
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';
}
source to share
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 .
source to share