954,496 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

help (overload << in a template class )

Hi, anyone can tell me what's wrong with my code? the only part has problem is the function overload << operator, any help is welcome.

#include
using namespace std;

template
class array
{
T data_[SIZE];
array (const array& other);
const array& operator = (const array& other);
public:
array(){};
T& operator[](int i) {return data_[i];}
const int getSize() const{return SIZE;};
const T& get_elem (int i) const {return data_[i];}
void set_elem(int i, const T& value) {data_[i] = value;}
operator T*() {return data_;}
friend ostream& operator<< (ostream&, const array&);
};

ostream& operator<< (ostream& out, const array& ar)
{
out<<"< ";
for(int i=0;i";
return out;
}

int main(void)
{
array intArray;
for(int i=0;i<10;i++) intArray.set_elem(i, i+100);
//std::cout<<" element 0: "<

alone2005
Newbie Poster
23 posts since Jun 2005
Reputation Points: 10
Solved Threads: 1
 

operator<< doesn't need to be a friend since you only use the public interface of array in it. A non-member function only needs to be a friend if it has to have access to a classes private or protected members.

#include <iostream>
using namespace std;

template <typename T, int SIZE>
class array
{
  T data_[SIZE];
  array (const array& other);
  const array& operator = (const array& other);
public:
  array(){};
  T& operator[](int i) {return data_[i];}
  const int getSize() const{return SIZE;};
  const T& get_elem (int i) const {return data_[i];}
  void set_elem(int i, const T& value) {data_[i] = value;}
  operator T*() {return data_;}
}; 

template <typename T, int SIZE>
ostream& operator<<(ostream& out, const array<T, SIZE>& ar)
{
  out<<"< ";
  for(int i=0;i<ar.getSize();i++) 
    out<<ar.get_elem(i)<<" ";
  out<<" >";
  return out;
}

int main(void)
{
  array<int, 10> intArray;
  for(int i=0;i<10;i++) intArray.set_elem(i, i+100);
  //std::cout<<" element 0: "<<intArray.get_elem(0)<<std::endl;
  //int firstElem = intArray.get_elem(0);
  //int* begin = intArray;
  cout<<intArray;
}
Dogtree
Posting Whiz in Training
233 posts since May 2005
Reputation Points: 35
Solved Threads: 3
 

Thanks a lot for the help! That solves my problem.
One more question (sorry i am messed by template), in case I don't have public interface and will access _data[] directly, then I will define << as a friend, how to write the code in that way? I always get non_template function warning when I format code as below.
/salute

#include <iostream>
using namespace std;

template <typename T, int SIZE>
class array
{
    T data_[SIZE];
    array (const array& other);
    const array& operator = (const array& other);
public:
    array(){};
    T& operator[](int i) {return data_[i];}
    const int getSize() const{return SIZE;};
    const T& get_elem (int i) const {return data_[i];}
    void set_elem(int i, const T& value) {data_[i] = value;}
    operator T*() {return data_;}    
    friend ostream& operator<<(ostream&, const array<T, SIZE>&);
};            

template <typename T, int SIZE>
ostream& operator<<(ostream& out, const array<T, SIZE>& ar)
{
	out<<"< ";
	for(int i=0;i<SIZE;i++) 
		out<<ar.data_[i]<<" ";
	out<<" >";
	return out;
}
   
int main(void)
{
	array<int, 10> intArray;
	for(int i=0;i<10;i++) intArray.set_elem(i, i+100);
	//std::cout<<" element 0: "<<intArray.get_elem(0)<<std::endl;
	//int firstElem = intArray.get_elem(0);
	//int* begin = intArray;
	cout<<intArray;
}
alone2005
Newbie Poster
23 posts since Jun 2005
Reputation Points: 10
Solved Threads: 1
 

write it this way and it works, but when I write function body of overload << out of class declaration
then I get error.

#include <iostream>
using namespace std;

template <typename T, int SIZE>
class array
{
    T data_[SIZE];
    array (const array& other);
    const array& operator = (const array& other);
public:
    array(){};
    T& operator[](int i) {return data_[i];}
    const int getSize() const{return SIZE;};
    const T& get_elem (int i) const {return data_[i];}
    void set_elem(int i, const T& value) {data_[i] = value;}
    operator T*() {return data_;}    
    friend ostream& operator<<(ostream& out, const array<T, SIZE>& ar){
	out<<"< ";
	for(int i=0;i<SIZE;i++) 
		out<<ar.data_[i]<<" ";
	out<<" >"<<endl;
	return out;
    }
};            

int main(void)
{
	array<int, 10> intArray;
	for(int i=0;i<10;i++) intArray.set_elem(i, i+10);
	//std::cout<<" element 0: "<<intArray.get_elem(0)<<std::endl;
	//int firstElem = intArray.get_elem(0);
	//int* begin = intArray;
	cout<<intArray;
}
alone2005
Newbie Poster
23 posts since Jun 2005
Reputation Points: 10
Solved Threads: 1
 

In that situation, you make the operator inline. The correct way to define it outside of your class is way too awkward to be practical:

#include <iostream>
using namespace std;

template <typename T, int SIZE> class array;
template <typename Ty, int sz>
ostream& operator<<(ostream& out, const array<Ty, sz>& ar);

template <typename T, int SIZE>
class array
{
  T data_[SIZE];
  array (const array& other);
  const array& operator = (const array& other);
public:
  array(){};
  T& operator[](int i) {return data_[i];}
  int getSize() {return SIZE;}
  const T& get_elem (int i) const {return data_[i];}
  void set_elem(int i, const T& value) {data_[i] = value;}
  operator T*() {return data_;}  

  friend ostream& operator<< <>(ostream& out, const array& ar);
};            

template <typename T, int SIZE>
ostream& operator<<(ostream& out, const array<T, SIZE>& ar)
{
  out<<"< ";
  for(int i=0;i<SIZE;i++) 
    out<<ar.data_[i]<<" ";
  out<<" >";
  return out;
}

int main(void)
{
  array<int, 10> intArray;
  for(int i=0;i<10;i++) intArray.set_elem(i, i+100);
  //std::cout<<" element 0: "<<intArray.get_elem(0)<<std::endl;
  //int firstElem = intArray.get_elem(0);
  //int* begin = intArray;
  cout<<intArray;
}
Dogtree
Posting Whiz in Training
233 posts since May 2005
Reputation Points: 35
Solved Threads: 3
 

Indeed it's difficult for me to understand why, but it truely works. Guess in practice i will follow the
first two ways as they are much more clear.
Many thanks for the help!

alone2005
Newbie Poster
23 posts since Jun 2005
Reputation Points: 10
Solved Threads: 1
 

can you berifly explain what compiler understand
when we declare template function befpre the class and declare it as friend function inside class and define it outside the class

Another Question
what this function mean

operator T*() {return data_;}

thank you in advance

farag
Junior Poster in Training
61 posts since Feb 2008
Reputation Points: 7
Solved Threads: 2
 

what this function mean

operator T*() {return data_;}


It returns a pointer to the member variable data_ of the array class.

mitrmkar
Posting Virtuoso
1,809 posts since Nov 2007
Reputation Points: 1,105
Solved Threads: 395
 

what about

can you berifly explain what compiler understand
when we declare template function befpre the class and declare it as friend function inside class and define it outside the class


Another question

the function

template <typename T, int SIZE>
ostream& operator<<(ostream& out, const array<T, SIZE>& ar)
{
  out<<"< ";
  for(int i=0;i<SIZE;i++) 
    out<<ar.data_[i]<<" ";
  out<<" >";
  return out;
}


gives an error if i replaced it by

template <typename T, int SIZE>
ostream& operator<<(ostream& out, const array<T, SIZE>& ar)
{
  out<<"< ";
  for(int i=0;i<SIZE;i++) 
    out<<ar.data_[i]<<" ";
  out<<" >";
  return out;
}


althougth the [] operator is overloaded before
plz reply and explain
thanks alot

farag
Junior Poster in Training
61 posts since Feb 2008
Reputation Points: 7
Solved Threads: 2
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You