Franky
Franky

Reputation: 1176

Issues on using operator<< for templates in C++ for a newbie

I'm new in using templates and also overloaded operators for them. This is my simple code. I tried to write an operator<< for the type T, but faced some odd error!

#include <iostream>
using namespace std;

template <class T>
class S {
    T val;

public:
    S<T>(T v) { val = v; }
};

template <class T>
ostream& operator<<(ostream& os, T& to) {
    return (os << to);
}

template <class T>
void write_val(T& t) {
    cout << t << endl;
}

int main()
{
    S<int> s1(5);
    write_val(s1);

    return 0;
}

I don't know:

  1. Why I face this error.
  2. What that kind of error is.
  3. And how to solve that and get the code run successfully.

Would you help me on above cases?

PS: This is a small part a bigger code. I separated this section because I think it is the source of my issue.

The error:

Unhandled exception at 0x00EEC529 in test3.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x00342F8C)

Upvotes: 0

Views: 51

Answers (2)

LogicStuff
LogicStuff

Reputation: 19607

This overloaded operator:

template <class T> ostream& operator<<(ostream& os, T& to) {
    return (os << to);
}

calls itself recursively, you can see it in the Call Stack window. Read up on Call Stack to know how it works and why and when stack overflow occurs. I mean, this site is called Stack Overflow, didn't you ever want to know what it stands for?

Solution:

The operator<< should be doing some real work instead, printing to.val, I suppose. Since S::val is private, you'll also have to declare it as a friend function to S.

template <class T>
class S {
    T val;

    template <class U>
    friend ostream& operator<<(ostream& os, S<U> const& to); // add some const

public:
    S<T>(T v) : val(v) {} // use member initializer list
};

template <class U>
ostream& operator<<(ostream& os, S<U> const& to) {
    return os << to.val;
}

Don't overload operator<< like this:

template <class T>
ostream& operator<<(ostream& os, T& to);

Because that template will match (almost) everything.

Upvotes: 3

template <class T> ostream& operator<<(ostream& os, T& to) {
    return (os << to);
}

The above is a recursive call. The function calls itself forever until the process eats up the call stack.

Upvotes: 2

Related Questions