关于使用运算符<<为新手提供C++中的模板

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

本文关键字:lt C++ 新手 运算符 于使用      更新时间:2023-10-16

我是使用模板的新手,也为模板重载运算符。这是我的简单代码。我试图为类型T编写一个operator<<,但遇到了一些奇怪的错误!

#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;
}

我不知道:

  1. 为什么我要面对这个错误
  2. 这种错误是什么
  3. 以及如何解决这一问题并使代码成功运行

你能帮我处理以上案件吗?

附言:这是一个较小的部分,一个较大的代码。我把这一部分分开是因为我认为这是我问题的根源。

错误:

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

这个重载运算符:

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

递归调用自身,您可以在调用堆栈窗口中看到它。阅读调用堆栈,了解它是如何工作的,为什么以及何时发生堆栈溢出。我的意思是,这个网站叫Stack Overflow,你难道不想知道它代表什么吗?

解决方案:

operator<<应该做一些实际的工作,打印to.val,我想。由于S::valprivate,您还必须将其声明为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;
}

不要像这样过载operator<<

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

因为该模板将匹配(几乎)所有内容。

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

以上是一个递归调用。函数永远调用自己,直到进程占用调用堆栈。