gpt4 book ai didi

c++ - 在模板类上重载 << 运算符

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:08:02 27 4
gpt4 key购买 nike

我已经为链表中的节点制作了一个模板类,我试图通过重载 << 将其内容输出到输出流。但是我当前的代码:

#include <iostream>
using namespace std;
template<class NType> class Node;

template<class NType>
class Node {
private:
void deletePointer(NType* p);
public:
NType data;
Node *prev, *next;

template<typename T>
struct is_pointer { static const bool value = false; };

template<typename T>
struct is_pointer<T*> { static const bool value = true; };

Node();
Node(NType data);
~Node();
};

int main() {
Node<int> *n1 = new Node<int>();
Node<int> *n2 = new Node<int>(10);

std::cout << "Node 1: " << n1 << std::endl;
std::cout << "Node 2: " << n2 << std::endl;
}

template<class NType> inline std::ostream & operator << (std::ostream& out, const Node<NType> &node){
out << node.data;
return out;
}

template<class NType> inline Node<NType>::Node()
:data(NULL), prev(NULL), next(NULL)
{
}

template<class NType> inline Node<NType>::Node(NType data)
:data(data), prev(NULL), next(NULL)
{
}

template<class NType> inline Node<NType>::~Node(){
if(is_pointer<NType>::value){
deletePointer(&data);
} else {
return;
}
}

template<class NType> inline void Node<NType>::deletePointer(NType* p){
delete p;
}

输出内存位置而不是节点内的数据。这种情况发生在 int 等基本类型上,就好像它不知道 NType 容器中的数据类型一样。

Node 1: 0x741010
Node 2: 0x741030
Node 3: 0x741070
Node 4: 0x741090

我已经尝试使用 typename 而不是 class 但仍然没有骰子......有什么方法可以动态找出模板正在使用的类型并进行转换或插入之前的东西?我知道我可以为所有原语编写大量冗余代码,但这似乎既浪费又不必要。

如果有帮助,我正在使用 GCC v4.6.2 20111223 在 Arch Linux x64 上编译

编辑: 因为很多人都提到它。我还尝试将类作为 friend 和独立函数放在外面,这两种方法都不起作用,因为无论我把它放在哪里,流都输出地址而不是数据本身。没有要访问的私有(private)数据值,所以它不是 friend 也没关系。

编辑:测试用例:http://ideone.com/a99u5还更新了上面的来源。

编辑:添加了我的代码的剩余部分以帮助 Aaron 理解代码。

最佳答案

您的代码声明了 operator<<作为一个成员函数,所以它实际上需要 this指针作为第一个参数和 ostream作为第二。相反,它需要是一个免费功能:

template<class NType> class Node {
public:
NType data;
Node *prev, *next;
};
//Note how this is declared outside of the class body, so it is a free function instead of a memberfunction
template<class NType> inline std::ostream& operator<<(std::ostream& out, const Node<NType>& val){
out << val.data;
return out;
}

但是,如果您的 operator<<需要访问私有(private)数据,您需要将其声明为友元函数:

template<class NType> class Node {
public:
NType data;
Node *prev, *next;
friend std::ostream& operator<<(std::ostream& out, const Node& val){
out << val.data;
return out;
}
};

现在输出:如果你的 operator<<被调用编译器会知道 NType 的类型并在流式传输 data 时做正确的事成员。但是自从你的operator<<不应该工作(如所写)并且它似乎给你 memoryaddresses 作为输出我假设你有如下内容:

Node* n = new Node();
std::cout<<n;
//When it should be:
std::cout<<*n;

现在只是出于好奇:你为什么要自己实现一个看起来很奇怪的链表而不是简单地使用 std::list

编辑:现在我们可以看到测试用例,它似乎是关于 operator<< 的假设。被称为是正确的。输出需要更改为:

std::cout << "Node 1: " << *n1 << std::endl;
std::cout << "Node 2: " << *n2 << std::endl;

实际调用 operator<<对于 Node ,而不是通用的 T*

关于c++ - 在模板类上重载 << 运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8813346/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com