我正在使用二叉树在C++中实现一个字典,我的二叉树中的每个节点都有一个键(
在这个实现过程中,我重载了我的
此外,我还重载了ostream,以便与
这个方法效果很好。但是,当我试图将树变成模板来处理任何类型的键或项时,重载这些运算符就变得更加困难了。
我将问题分离出来,使它更容易处理。此外,我尝试使用node和node指针来玩耍,看看是否可以让其中一个工作而不需要另一个。
以下是我制作的用于测试问题的类,此类未被模板化,效果良好。 test.h
通过这个类,我可以轻松地创建一个实例并使用
代码无法编译,因为出现了以下错误:
此外,将该行注释掉:
int
)、项目(string
)以及左、右孩子。在这个实现过程中,我重载了我的
BinaryTree
类的ostream运算符,以打印出树的内容。此外,我还重载了ostream,以便与
Node
指针一起使用,然后打印出该节点的key和item。这个方法效果很好。但是,当我试图将树变成模板来处理任何类型的键或项时,重载这些运算符就变得更加困难了。
我将问题分离出来,使它更容易处理。此外,我尝试使用node和node指针来玩耍,看看是否可以让其中一个工作而不需要另一个。
以下是我制作的用于测试问题的类,此类未被模板化,效果良好。 test.h
class myClass
{
public:
using Key = int;
myClass(Key);
friend std::ostream & operator<<(std::ostream &, const myClass &);
private:
struct Thing {
Key data;
Thing();
Thing(Key);
};
Thing* B;
Thing A;
void disp(std::ostream &) const;
friend std::ostream & operator<<(std::ostream &, myClass::Thing);
friend std::ostream & operator<<(std::ostream &, myClass::Thing *);
};
test.cpp
myClass::Thing::Thing(Key Num) { data = Num; }
myClass::myClass(Key Num)
{
A = Thing(Num); B = &A;
}
void myClass::disp(std::ostream & os) const
{
os << A << std::endl; os << B << std::endl;
}
std::ostream & operator<<(std::ostream & os, const myClass & c)
{
c.disp(os); return os;
}
std::ostream & operator<<(std::ostream & os, myClass::Thing th)
{
os << th.data; return os;
}
std::ostream & operator<<(std::ostream & os, myClass::Thing *th)
{
os << th->data; return os;
}
通过这个类,我可以轻松地创建一个实例并使用
std::cout
输出期望的结果。
然后将这个类转换为模板:template <class T> class myTemplate
{
public:
using Key = T;
myTemplate(Key);
template<class A>
friend std::ostream & operator<<(std::ostream &, const myTemplate<A> &);
private:
struct Thing;
Thing A;
Thing* B;
void disp(std::ostream &) const;
template <class A> friend std::ostream & operator<<(std::ostream &, typename myTemplate<A>::Thing);
template <class A> friend std::ostream & operator<<(std::ostream &, typename myTemplate<A>::Thing *);
};
template <class T> struct myTemplate<T>::Thing
{
T data;
Thing() = default;
Thing(Key);
};
//Create new thing A with B a pointer to A
template <class T> myTemplate<T>::myTemplate(Key Num)
{
A = Thing(Num);
B = &A;
}
//Displays Node A & B
template <class T> void myTemplate<T>::disp(std::ostream & os) const
{
os << A << std::endl; os << B << std::endl;
}
template <class T> myTemplate<T>::Thing::Thing(Key Num)
{
data = Num;
}
//Overloading << will call disp function, in turn print A & B to stream
template<class T> std::ostream & operator<<(std::ostream & os, const myTemplate<T> & c)
{
c.disp(os); return os;
}
//Output a to stream
template <class A> std::ostream & operator<<(std::ostream & os, typename myTemplate<A>::Thing th)
{
os << th.data; return os;
}
//Output a to stream
template <class A> std::ostream & operator<<(std::ostream & os, typename myTemplate<A>::Thing *th)
{
os << th->data; return os;
}
然而,当我在main()
中尝试使用myTemplate
时:
myTemplate Template(5);
cout << Template;
代码无法编译,因为出现了以下错误:
Error C2679 binary '<<': no operator found which takes a right-hand operand of type 'const myTemplate<std::string>::Thing' (or there is no acceptable conversion)
此外,将该行注释掉:
os << A << std::endl;
只有 B
被输出到流中,代码将会编译。然而,B
的数据没有被输出,只有 B
的内存地址。
我注意到在尝试输出 B
时使用断点,代码甚至没有使用我定义的重载函数。这不适用于非模板类,因为我定义的重载对于 A
和 B
都适用。
那么,重载 ostream 运算符以使其适用于结构体成员的正确方法是什么?
抱歉问题有些冗长,但我觉得应该包括我自己所确定的内容。
Thing
? - Matthieu Brucheroperator<<
。在你的问题中写尽可能少的代码,这样你会吸引更多的关注。tl;dr. - YSC