ostream in template class

any idea whats the problem with the ostream ?

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
#pragma once
#include<iostream>
using namespace std;



template<class T>
class p {
	T x;
	T y;
	
public:
	p();
	p(T, T);
	p(const p&);
	template<class T>
	friend ostream& operator<<(ostream & out, const p<T> &o);
};

template<class T>
p<T>::p() {
	x = y = 0;
}
template<class T>
p<T>::p(T a, T b) {
	x = a;
	y = b;
}
template<class T>
p<T>::p(const p& obj) {
	x = obj.x;
	y = obj.y;
}
template<class T>
ostream& operator<<(ostream & out, const p<T> &o) {
	out << "(" << o.x << "," << o.y << ")" << endl;
	return out;
}





Last edited on
The problem is that you have two different operator<<. One inside the class (just a prototype) and one outside the class. For the compiler they are not related.
ok fixed it coder777 tnx alot by doing it inline method.
Last edited on
Unfortunately you do not tell what the error is nor do you provide code to reproduce the problem.

Probably the compiler does not like the redefinition of template<class T> on line 16?
Either define the friend function inline:
1
2
3
4
5
6
7
8
template < typename T > struct pt1
{
    T x {} ;
    T y {} ;

    friend std::ostream& operator<< ( std::ostream& stm, const pt1& p )
    { return stm << '(' << p.x << ',' << p.y << ')' ; }
};


Or clarify that the friend function is a template:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template < typename T > struct pt2 ; // declare the class template
template < typename T > std::ostream& operator<< ( std::ostream& stm, const pt2<T>& p ) ; // declare the function template

template < typename T > struct pt2
{
    T x {} ;
    T y {} ;

    // add <> after the name of the function to inform the compiler that the friend
    // declaration declares a template (without <>, it declares a non-template)
    friend std::ostream& operator<< <> ( std::ostream& stm, const pt2<T>& p ) ;
};

template < typename T > std::ostream& operator<< ( std::ostream& stm, const pt2<T>& p )
{ return stm << '(' << p.x << ',' << p.y << ')' ; }

http://coliru.stacked-crooked.com/a/a25b34aa2531484d

More information: https://isocpp.org/wiki/faq/templates#template-friends
Yet another possibility is the unbound friend function template to the class template – by declaring a function template inside the class template you can create unbound friend functions for which every function specialization is a friend to every class specialization. For unbound friends, the friend template type parameters are different from the class template type parameters:
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
# include <iostream>
# include <string>

template < typename T > struct pt2
{
    T m_x {} ;
    T m_y {} ;

    pt2(const T x, const T y) : m_x(x), m_y(y){}

    template <typename U>
    friend std::ostream& operator << ( std::ostream& stm, const pt2<U>& p );
};

template <typename U>
std::ostream& operator << (std::ostream& stm, const pt2<U>& p)
{
    stm << p.m_x << " " << p.m_y << "\n";
    return stm;
}

int main()
{
    pt2<int> p_int(1, 2);
    pt2<double> p_double(3.4, 5.6);
    pt2<std::string> p_string("hello", "world");

    std::cout << p_int << p_double << p_string << "\n";
}

However there is one downside to this approach – any particular instantiation of pt2<T> provides access to all instantiations of the operator << overloads i.e. std::ostream& operator << (std::ostream& , const pt2<std::string>&) has access to all internals of pt2<int> and so on … this is precluded by the second approach in the previous post – a single instantiation of the function template is now declared to be a friend of the class template without exposing the other instantiations
Topic archived. No new replies allowed.