简体   繁体   中英

C++ templates and friend declaration

Can someone tell me whats wrong with my code. I'm guessing that I didn't overload << correctly, but I'm not sure how to fix it.

The below code implements a simple Stack container. It fails at cout << si;

update: Made suggested changes, still not compiling.

update2: Got it! Thanks!

#include <iostream>
using namespace std;

template <typename T = int, int N = 10>
struct Stack
{
    T elems[N];
    unsigned int size;

    Stack()
    {
        size=0;
    }

    void push(T e)
    {
        elems[size]=e;
        size++;
    }

    T pop()
    {
        size--;
        return elems[size];
    }

            template <typename T, int N>
    friend ostream& operator << (ostream& os, const Stack<T, N> &stack);
};

template <typename T, int N>
ostream& operator << (ostream& os, const Stack<T, N> &stack)
{
    for (unsigned int i=0; i<N; i++)
    {
        os << stack.elems[i];
    }

    return os;
}


int main()
{   

    Stack<> si;
    si.push(3);
    cout << si;

}

Should be

ostream& operator << (ostream& os, const Stack<T,N> &stack);
//                                              ^^ -- note this

in both definition and declaration.

You need to fully specify all template arguments for your stack here:

template <typename T, int N>
ostream& operator<< (ostream& os, const Stack<T, N> &stack);

other wise the compiler can't deduce the proper N for your overloaded streaming operator.

template <typename T, int N>
ostream& operator << (ostream& os, const Stack<T> &stack)

The problem with this template is that the parameter N cannot be inferred from either of the function arguments because you are using the default template argument for the Stack argument.

Looking at your implementation, you almost certainly didn't intend this as you use N as the loop bound whereas Stack<T> has 10 elements. You probably meant to write:

template <typename T, int N>
ostream& operator << (ostream& os, const Stack<T, N> &stack)

Also, your friend declaration needs to match the template, at the moment the friend declaration is declaring a non-template friend overload.

This would declare an appropriate friend template.

template< typename S, int M >
friend ostream& operator << (ostream& os, const Stack<S, M> &stack);

You already got your answers, but may I suggest turning:

void push(T e) 

into:

void push(const T& e) 

for performance wise, since you have no idea what T will be, and passing it on the stack isnt a good idea.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM