Reputation: 73
I'm making my first binary search tree. I have a BinarySearchTreeNode nested inside of BinarySearchTree. I'm trying to overload the << operator for BinarySearchTreeNode, but I can't figure out how to get it to compile.
{
template<class Type>
class BinarySearchTree
{
//Forward declare classes
public:
class BinarySearchTreeNode;
//Declare
public:
BinarySearchTree();
private:
BinarySearchTreeNode *head;
//Nested classes:
public:
class BinarySearchTreeNode
{
friend std::ostream& operator <<(std::ostream &outs, const BinarySearchTreeNode& node);
public:
BinarySearchTreeNode();
BinarySearchTreeNode(const Type &data);
BinarySearchTreeNode *getRight() const;
BinarySearchTreeNode *getLeft() const;
void insert(const Type &data);
const Type &getData() const;
std::string recursiveToString();
private:
Type data;
List<int> lineNumbers;
BinarySearchTreeNode *left;
BinarySearchTreeNode *right;
void addNode(Type data);
void setRight(Type data);
void setLeft(Type data);
};
};
}
template<class Type>
std::ostream& cs20a::operator <<(std::ostream &outs, const typename BinarySearchTree<Type>::BinarySearchTreeNode& node)
{
outs << node.getData();
return outs;
}
This won't compile because it says that there is no matching declaration in the namespace cs20a. I can't figure out how to get it to compile. The only way I can get it to work is if I put the function definition at the top instead of declaring it at the top. My professor wants them all separate if possible.
Thank you
Upvotes: 2
Views: 68
Reputation: 206607
Here's a skeletal program that builds successfully for me, using g++ 4.8.4. I have added comments in the code to explain what I have done.
#include <iostream>
using namespace std;
namespace cs20a
{
// Declare the class template.
template <class Type> class BinarySearchTree;
// Declare the operator<<() function.
template <typename T> std::ostream& operator<<(std::ostream &outs,
const typename BinarySearchTree<T>::BinarySearchTreeNode& node);
template<class Type> class BinarySearchTree
{
public:
BinarySearchTree();
class BinarySearchTreeNode
{
// Make operator<<() a friend.
// This syntax makes sure that operator<< <int> is a friend of
// BinarySearchTree<int>::BinarySearchTreeNode but not a friend
// of BinarySearchTreeNode<double>::BinarySearchTreeNode.
friend std::ostream& operator<< <Type>(std::ostream &outs, const BinarySearchTreeNode& node);
public:
const Type &getData() const;
};
private:
BinarySearchTreeNode *head;
};
}
// Implement the function.
template<class Type>
std::ostream& cs20a::operator<<(std::ostream &outs,
const typename BinarySearchTree<Type>::BinarySearchTreeNode& node)
{
outs << node.getData();
return outs;
}
int main()
{
return 0;
}
Upvotes: 0
Reputation: 172924
You could just add a declaration at the last of the namespace defination:
// ... ...
};
};
template<class Type>
std::ostream& operator <<(std::ostream &outs, const typename BinarySearchTree<Type>::BinarySearchTreeNode& node);
}
template<class Type>
std::ostream& cs20a::operator <<(std::ostream &outs, const typename BinarySearchTree<Type>::BinarySearchTreeNode& node)
{
outs << node.getData();
return outs;
}
Upvotes: 1