Doug
Doug

Reputation: 77

operator<< overloading to call a print function trouble

Okay I'm a little stuck on trying to overload the << operator for my template class. The requirement is that the << operator must call a void print function defined for this class.

Here is the important stuff from the template header:

template <class T>
class MyTemp {
public:
    MyTemp();           //constructor

    friend std::ostream& operator<< (std::ostream& os, const MyTemp<T>& a);

    void print(std::ostream& os, char ofc = ' ') const;

and here is my print function basically it's a vector and prints last element to first:

    template <class T>
void Stack<T>::print(std::ostream& os, char ofc = ' ') const
{
    for ( int i = (fixstack.size()-1); i >= 0 ; --i)
    {
        os << fixstack[i] << ofc;
    }
}

and here is how I have the operator<< overloaded:

    template <class T>
std::ostream& operator<< (std::ostream& os, const Stack<T>& a)
{
    // So here I need to call the a.print() function
}

But I am receiving an "unresolved external symbol" error. So really I guess I have two issues. The first, is the way to fix the error above. Second, once that is fixed would I just call a.print(os) inside << overload? I know it needs to return an ostream though. Any help would be greatly appreciated!

Upvotes: 0

Views: 417

Answers (3)

Mike Seymour
Mike Seymour

Reputation: 254501

The simplest thing to do would be to leave print public (as it is in your example), so the operator doesn't need to be a friend.

template <class T>
class MyTemp {
public:
    void print(std::ostream& os, char ofc = ' ') const;
};

template <class T>
std::ostream& operator<< (std::ostream& os, const MyTemp<T>& a) {
    a.print(os);
    return os;
}

If you do need it to be private, then you need to declare the correct template specialisation to be a friend - your friend declaration declares a non-template operator in the surrounding namespace, not a template. Unfortunately, to make a template a friend you need to declare it beforehand:

// Declare the templates first
template <class T> class MyTemp;
template <class T> std::ostream& operator<< (std::ostream&, const MyTemp<T>&);

template <class T>
class MyTemp {
public:
    friend std::ostream& operator<< <>(std::ostream& os, const MyTemp<T>& a);
    // With a template thingy here  ^^

private:
    void print(std::ostream& os, char ofc = ' ') const;
};

template <class T>
std::ostream& operator<< (std::ostream& os, const MyTemp<T>& a) {
    a.print(os);
    return os;
}

Or you could define the operator inline:

template <class T>
class MyTemp {
public:
    friend std::ostream& operator<<(std::ostream& os, const MyTemp<T>& a) {
        a.print(os);
        return os;
    }

private:
    void print(std::ostream& os, char ofc = ' ') const;
};

For your last question:

Second, once that is fixed would I just call a.print(os) inside << overload? I know it needs to return an ostream though.

It does indeed need to return an ostream - so just return the one that was passed in, as in my example code.

Upvotes: 2

ken
ken

Reputation: 836

This error means there is an symbol which could not be recognized by the linker.on what variable are u getting this error and also please check on stack as well because there is a std::stack class available.

Upvotes: 1

Didier Trosset
Didier Trosset

Reputation: 37447

As your print member function is public, there's no need to declare operator<< as friend.

Beware that you are using class Stack is your overload, and MyTemp above ...

Upvotes: 0

Related Questions