jaredjxyz
jaredjxyz

Reputation: 73

Proper syntax for separating declaration and definition for Operator overloading << in templated nested classes?

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

Answers (2)

R Sahu
R Sahu

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

songyuanyao
songyuanyao

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

Related Questions