Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

operator << problem

Status
Not open for further replies.

maur3r

Technical User
Aug 28, 2006
34
PL
Hi I am trying to overload << operator for a simple class

Code:
class String
{
    private:
        std::list<std::string> data;
    public:
        //some simple functions
}
;

Unfortunately my approach to overloading << doesn't work
Code:
inline std::ostream& operator<<(std::ostream& os, const String &str)
{
  std::list<std::string>::iterator idx;
  idx=(str.data).begin()	;	
  //for(idx=str.data.begin(); idx!=str.data.end(); ++idx)
      os<<*idx<<endl;
  return os;
}
The error is as following
Code:
 error: no match for ‘operator=’ in ‘idx = str->String::data. std::list<_Tp, _Alloc>::begin [with _Tp = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Alloc = std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >]()’
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_list.h:112: note: candidates are: std::_List_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >& std::_List_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::operator=(const std::_List_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >&)
Does anybody know how to fix it?
I'm using Ubuntu 6.10 and standard g++ compiler

Regards, Martin

(OS and comp.)
using Linux and gcc
 
I've already solved a problem in a slightly different way
Code:
#include <string>
#include <sstream>
#include <iostream>
#include <vector>

using namespace std;

class String
{
  private:
        std::vector<std::string> data;
     public:
        //default constructor
        String() : data()
        {
        }

        //conversion constructor for string literals
        String(const char *str) : data()
        {
         data.push_back(str);
        }

        //copy constructor
        String(const String &str)
        {
            data = str.data;
        }

        template <class T> String& operator<<(const T& inp)
        {
            std::stringstream ss;

            ss << inp;
            data.push_back(ss.str());
            return *this;
        }

        friend String operator+(const String &, const String &);
        friend std::ostream& operator<<(std::ostream&, const String &);
};

inline String operator+(const String &s1, const String &s2)
{
String res;
std::vector<string>::const_iterator idx;
for(idx=s1.data.begin(); idx!=s1.data.end(); idx++)
res.data.push_back(*idx);
for(idx=s2.data.begin(); idx!=s2.data.end(); idx++)
res.data.push_back(*idx);
return res;
}

inline std::ostream& operator<<(std::ostream& os, const String &str)
{
std::vector<string>::const_iterator idx;
for(idx=str.data.begin(); idx!=str.data.end(); idx++)
os<<*idx;
return os;
}

int main()
{String s;
s << "3*4 = " << 3 * 4;
cout << s << endl; // outputs "3*4 = 12"

String p(" And so on");
cout << p << endl;  // outputs " And so on"

String f = s + p;
cout << f << endl;  // outputs "3*4 = 12 And so on"
}
Guess that previous example' problem was with iterator instead of const_iterator.

Regards, Martin

(OS and comp.)
using Linux and gcc
 
data is private. Did you declare your operator<<() as a friend to String?
Maybe adding these to the public section of String would be better:
Code:
typedef std::list<std::string>::iterator  iterator;

iterator  begin()
{ return data.begin(); }

iterator  end()
{ return data.end(); }
Then you can just say:
Code:
String::iterator idx;

for( idx = str.begin(); idx != str.end(); ++idx )
Then you don't have to worry about making it a friend.
 
The other option is to write a print() member function and call it from the << operator...

This is fairly common, especailly for writing a compareTo(...) which returns a number less than 0 if less than, 0 if equal to, and posive numver for greater than... which make overloading <, >, == and != simple. It will also be second nature if you program in Java at all, and implement comparable often enough.

[plug=shameless]
[/plug]
 
That's all right but it's interesting: the error in the original post was caused not a private member access but read/write iterator instead of const_iterator (remember const String &str).
 
ArkM,

Good catch, but maur3r's already figured that out. They were pointing out the other reason he missed on why his first code wouldn't have worked. And I suggested an alternative method of doing it.

[plug=shameless]
[/plug]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top