c++模板和友元声明

C++ templates and friend declaration

本文关键字:友元 声明 c++      更新时间:2023-10-16

谁能告诉我我的代码有什么问题?我猜我没有正确地重载<<,但我不确定如何修复它。

下面的代码实现了一个简单的Stack容器。在cout << si; 失效

update:已完成建议的修改,但仍未编译。

update2:知道了!谢谢!

#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;
}
template <typename T, int N>
ostream& operator << (ostream& os, const Stack<T> &stack)

这个模板的问题是不能从函数参数中推断出参数N,因为您正在使用Stack参数的默认模板参数。

看看你的实现,你几乎肯定没有打算这样做,因为你使用N作为循环边界,而Stack<T>有10个元素。你可能想写:

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

同时,你的友元声明需要与模板匹配,此时友元声明正在声明一个非模板的友元重载。

声明一个合适的友元模板。

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

应该是

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

您需要在这里完整指定堆栈的所有模板参数:

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

否则,编译器无法为您的重载流操作符推断出正确的N

你已经得到了你的答案,但是我可以建议你转向:

void push(T e) 

为:

void push(const T& e) 

在性能方面,因为你不知道T将是什么,并且在堆栈上传递它不是一个好主意。