简体   繁体   中英

Template errors: unresolved externals and inner friend classes

I'm writing a binary search tree using templates. The idea is that I have a pure abstract base class with virtual operator overload functions used for comparing it with other classes which inherit it of the same type. This class, or rather any class which inherits from it, represents the "key" in the BST.

A good example would be what I plan to do with this in the beginning, which is add shader sources (in strings, parsed from shader files) to the BST as values, with the key being a type of ShaderComparable , which holds the filename of the shader, and is used for key comparisons within the BST.

The problem is that, while when I was writing the code it would compile fine, as soon as I stick an instance of the BST class in main and try to run it, I get link "unresolved external" errors.

Code

SearchTree.hpp

#pragma once

#include <stdint.h>
#include "Comparable.hpp"

namespace esc
{ 
    /*
     * NOTE: K must inherit from type 'Comparable', located in "Comparable.hpp"
     */

    template < typename TComparable, typename TValue > 
    class SearchTree
    {
    public:
        class Iterator;
    private:
        struct Node;
        typedef typename Node TNode;
    public:
        SearchTree( void );
        ~SearchTree( void );
    public:
        //TValue find( const TComparable& k );
        //TValue find( int32_t index );
        //TValue find( const Iterator& pIter );

        //Iterator begin( void ) const;
        //Iterator end( void ) const;

        void insert( const TComparable& k, const TValue& v );
        //void insert( const Iterator& pIter );

        friend class Iterator;
    private:
        int32_t mNodeCount;
        TNode* mRoot;
    public:
        class Iterator 
        {
        public:
            Iterator( void );   
            inline TNode* operator->( void ) const 
            { return mCurrentNode; }
        private:
            ~Iterator( void );
            int32_t getNumStepsLeftToLeaf( void );
            int32_t getNumStepsRightToLeaf( void );
            void tallyDirectionalComparison( int& numLeftTrue, int& numRightTrue, const TComparable& k );
            void insertLeft( const TComparable& k, const TValue& v );
            void insertRight( const TComparable& k, const TValue& v );
            bool isLeafNode( const Node*& a );
            bool isInternalNode( const Node*& node );
        private:
            TNode* mCurrentNode;
            int32_t mIterPosition;
            friend class Node;
        };
    private:
        struct Node
        {
        public:
            int32_t index;
            TComparable Key;
            TValue Value;
        private:
            TNode* mParent;
            TNode* mLeftChild;
            TNode* mRightChild;
        };
    };
}

SearchTree.cpp

template < typename TComparable, typename TValue >
    SearchTree< TComparable, TValue >::SearchTree( void )
        : mRoot( NULL ),
          mPosition( 0 ), 
          mNodeCount( 0 )
    {}

    template < typename TComparable, typename TValue >
    SearchTree< TComparable, TValue >::~SearchTree( void )
    {
        //TODO
    }

There's more code in the source, I just didn't want to post it all, in hopes to avoid ambiguity. The iterator definitions are typically of something along the lines of this:

template < typename TComparable, typename TValue >
void SearchTree< TComparable, TValue >::Iterator::insertRight( const TComparable& k, const TValue& v )

etc.

Errors

1>Main.obj : error LNK2019: unresolved external symbol "public: __thiscall esc::SearchTree<class esc::ShaderComparable,struct esc::Shader>::~SearchTree<class esc::ShaderComparable,struct esc::Shader>(void)" (??1?$SearchTree@VShaderComparable@esc@@UShader@2@@esc@@QAE@XZ) referenced in function _main

1>Main.obj : error LNK2019: unresolved external symbol "public: __thiscall esc::SearchTree<class esc::ShaderComparable,struct esc::Shader>::SearchTree<class esc::ShaderComparable,struct esc::Shader>(void)" (??0?$SearchTree@VShaderComparable@esc@@UShader@2@@esc@@QAE@XZ) referenced in function _main

Question

Why am I getting these errors? What can I do to stop these?

I'm guessing it's because you've made some of your destructors private. Try making them public.

Class template member function bodies need to be in the header (SearchTree.hpp), not in the .cpp file. See here for the Stack Overflow canonical response on this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM