Operator Overloading with Templates

Hi!
I'm trying to overload << operator and running into an error that says function template partial specialization is not allowed. I really don't understand what is partial specialization and also where exactly have I gone wrong in my code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#ifndef CCOORDINATE_H_
#define CCOORDINATE_H_

#include <iostream>
#include <cmath>

using namespace std;

template<class T>
class CComplex
{
	friend ostream& operator<<<T>(ostream& out, const CComplex<T>& obj);

private:
	T m_imaginary;
	T m_real;

public:
	CComplex();
	CComplex(T, T);
};

template<class T>
CComplex<T>::CComplex()
{
	m_imaginary = 0;
	m_real = 0;
}

template<class T>
CComplex<T>::CComplex(T x, T y)
{
	m_imaginary = x;
	m_real = y;
}

template<class T>
ostream& operator<<<T>(ostream& out, const CComplex<T>& obj)
{
	if (obj.m_imaginary > 0)
	{
		out << obj.m_real << " + i" << obj.m_imaginary;
	}
	if (obj.m_imaginary < 0)
	{	float temp = -obj.m_imaginary;
		out << obj.m_real << " - i" << temp;
	}
	if (obj.m_imaginary == 0)
	{
		out << obj.m_real;
	}
	return out;
}
#endif 
How about this:

line 12:
friend ostream& operator<< (ostream& out, const CComplex<T>& obj);

And the definition:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template<class T>
ostream& operator<<(ostream& out, const CComplex<T>& obj)
{
	if (obj.m_imaginary > 0)
	{
		out << obj.m_real << " + i" << obj.m_imaginary;
	}
	if (obj.m_imaginary < 0)
	{	float temp = -obj.m_imaginary;
		out << obj.m_real << " - i" << temp;
	}
	if (obj.m_imaginary == 0)
	{
		out << obj.m_real;
	}
	return out;
}
when i do that then i get an error: undefined reference to the operator << when i try this in my main()
1
2
CComplex<int> a1(2,2);
    cout << a1 << endl;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template < typename T > class A ; // declare the class (template)

// declare the function (template)
template < typename T > std::ostream& operator<< ( std::ostream&, const A<T>& ) ;

template<class T> class A
{
    // declare the friend as a template
    friend std::ostream& operator<< <> ( std::ostream&, const A<T>& obj ) ;
    // ...
};

// define the the function (template)
template < typename T > std::ostream& operator<< ( std::ostream& stm, const A<T>& a )
{
    // stm << ...

    return stm ;
}


See: http://www.parashift.com/c++-faq/template-friends.html
Last edited on
(from that link)
> Another approach is to define the friend function within the class body at the same moment you declare it to be a friend.
Tried with a forward declaration and still ran into errors. Then tried defining the friend function within the class itself and that's working. However one thing I cannot understand is if I define the function in any of these ways:

1
2
friend ostream& operator<< <> (ostream& out, const CComplex<T>& obj)
{ .... }


or

1
2
friend ostream& operator<< <T> (ostream& out, const CComplex<T>& obj)
{ .... }


it throws some error, but this works just fine:

1
2
friend ostream& operator<< (ostream& out, const CComplex<T>& obj)
{ .... }


isn't << in a sense a function and the template associated with it should be given?
Topic archived. No new replies allowed.