1

I've been searching for a while and the closest thing to an answer was over there

toString override in C++

However I was not able to make it work in my class.

I have a Table2D.h which contains this:

std::string toString() const;
std::ostream & operator<<( std::ostream & o, const Table2D<T> & s );

and I have a template class Table2D.template which contains this:

template <class T>
std::ostream & :: operator<<( std::ostream & o, const Table2D<T> & s ){
    return out << s.toString();
}

when I call my toString() function from main, it functions correctly. However when I invoke the << operator using a std::cout I get the following errors.

Table2D.h(59): error C2804: binary 'operator <<' has too many parameters
Table2D.h(85) : see reference to class template instantiation 'Table2D<T>' being compiled
Table2D.template(100): error C2039: '<<' : is not a member of '`global namespace''
Table2D.h(59): error C2804: binary 'operator <<' has too many parameters

just so you know the 59'th line contains

for (unsigned y=0; y<m_height; y++) col_ptr[y] = (T) col_ptr_src[y];

which as you see contains no <<'s so I'm not entirely certain what it's referring to.


Edit:

After removing the declaration from the class, I replaced it's entry in the header file with this

template <class T>
std::ostream& operator<<( std::ostream& o, const Table2D<T>& s ) {
    return o << s.toString();
}

and got the following error:

Table2D.h(60): error C2804: binary 'operator <<' has too many parameters
Table2D.h(89) : see reference to class template instantiation 'Table2D<T>' being compiled

the 89th line in the template file contains std::stringstream resultStream;

which is the very first line in my toString function, which looks like this

template <class T>
std::string Table2D<T> :: toString() const{
    std::stringstream resultStream;
    for(unsigned i = 0; i< m_height; i++){
        for (unsigned j = 0; j < m_width; j++){
            resultStream << (*this)[i][j] << "\t";
        }
        resultStream << endl;
    }
    return resultStream.str();
}
Community
  • 1
  • 1
vvMINOvv
  • 1,768
  • 4
  • 22
  • 45
  • thank's @pst I'm having a lot of trouble identifying errors with c++ so my question names can be a little off. Thank's again. – vvMINOvv Nov 23 '11 at 02:38
  • 1
    In case you don't know, click on the number circled in red on the top left of the page to see the comments directed at you via the @-symbol. If you do you'll see my comment to you in my answer. – Seth Carnegie Nov 23 '11 at 02:49

1 Answers1

5

Aside from your syntax being wrong1, operator<< overloads on other classes (ostream in this case) must be non-member functions. Change your definition to

template <class T>
std::ostream& operator<<( std::ostream& o, const Table2D<T>& s ) {
    return o << s.toString();
}

and remove its declaration from the class completely so that it is a free function.


1 In case you want to know why, member-function binary operators only take one argument, because the left side is the invoking object, accessed via this. Also, you forgot the Table2D<T> before the :: in the definition. But even if you fixed these it wouldn't work as intended because, as previously stated, operator overloading on other classes must be done through free functions.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • I don't know how to post code in these comment boxes so I'll just edit my post with the reply gimme a sec – vvMINOvv Nov 23 '11 at 02:37
  • 1
    @vvMINOvv update your code in your question to reflect exactly what you're compiling now, and update the error you're getting (copy and paste it, don't try to type it). – Seth Carnegie Nov 23 '11 at 02:37
  • I swear I love this place. You guys are awesome. – vvMINOvv Nov 23 '11 at 02:44
  • 1
    @vvMINOvv just to make sure, you have `template ` above the `operator<<` thing, and also it is **completely outside the class**, right? Not inside the class's curly braces? And yeah, SO is a cool place. – Seth Carnegie Nov 23 '11 at 02:45
  • @Seth_Carnegie thank's buddy, you've been really patient with me. – vvMINOvv Nov 23 '11 at 02:52
  • @Seth_Carnegie so yea I just checked and it's exactly as you told me to write it. I have `template ` right above in the header file, under `public:` – vvMINOvv Nov 23 '11 at 02:53
  • 1
    @vvMINOvv yeah, it shouldn't be under public, it should be outside the class completely. Example: http://pastebin.com/suy0tQ0Z – Seth Carnegie Nov 23 '11 at 02:54
  • @Seth_Carnegie wow.....that is bizzarre, how does it know which scope `toString()` I was referring to then? is it because of the s parameter? – vvMINOvv Nov 23 '11 at 03:05
  • 1
    @vvMINOvv because of the type of `s`, yes. The compiler knows everything about it (because of its type which it has already seen) including all its member functions, so it knows what to do. – Seth Carnegie Nov 23 '11 at 03:06