I know what I want, but I don't know how to tell the compiler what I want. I have split declarations and method definitions in .h and .cpp file, but the .cpp file gets included in the header, so all I did was separate declarations and definitions.
header file (avltree.h) - it includes the source file!:
template < class KEY_T, class DATA_T >
class CAvlTree {
public:
//----------------------------------------
template < class KEY_T, class DATA_T >
class CNode;
typedef CNode< KEY_T, DATA_T> * tNodePtr;
template < class KEY_T, class DATA_T >
class CNode {
public:
KEY_T key;
DATA_T data;
CNode< KEY_T, DATA_T > * left;
CNode< KEY_T, DATA_T > * right;
char balance;
CNode() : left(nullptr), right(nullptr), balance(0) {}
CNode(KEY_T key, DATA_T data) :
key (key), data (data), left(nullptr), right(nullptr), balance(0) {}
};
//----------------------------------------
template < class KEY_T, class DATA_T >
struct tAvlInfo {
CNode< KEY_T, DATA_T> * root;
CNode< KEY_T, DATA_T> * current;
KEY_T key;
bool isDuplicate;
bool branchChanged;
};
typedef bool (* tNodeProcessor) (CNode< KEY_T, DATA_T> * nodePtr);
private:
tAvlInfo< KEY_T, DATA_T > m_info;
//----------------------------------------
public:
DATA_T* Find(KEY_T& key);
private:
CNode< KEY_T, DATA_T> * AllocNode(void);
};
#include "avltree.cpp"
source file (avltree.cpp):
template < typename KEY_T, typename DATA_T >
DATA_T* CAvlTree< KEY_T, DATA_T >::Find (KEY_T& key)
E0276 name followed by '::' must be a class or namespace name
{
CNode* root;
for (CNode* node = m_info.root; node; ) {
if (key < node->key)
node = node->left;
else if (key > root->key)
node = node->right;
else {
m_info.current = node;
return &node->data;
}
}
return nullptr;
}
template < typename KEY_T, typename DATA_T >
CNode* CAvlTree< KEY_T, DATA_T >::AllocNode (void)
E0020 identifier "CNode" is undefined
E0864 CAvlTree is not a template
{
if (m_info.current = new CNode < KEY_T, DATA_T >) {
m_info.branchChanged = true;
return m_info.current;
}
return nullptr;
}
What the compiler says (VS 2019 community, c++2020 enabled):
E0276 name followed by '::' must be a class or namespace name
E0020 identifier "CNode" is undefined
E0864 CAvlTree is not a template
I have no bloody clue how to write this down the correct way. Please enlighten me.
I have similar code for a template class with a single typename which works, but cannot conclude from that how to do this for two typenames.
Using the tNodePtr type instead of CNode< KEY_T, DATA_T > * in my source code also doesn't work.
Btw, I know that the compiler doesn't "transfer" KEY_T and DATA_T from the CAvlTree declaration just because I am using the same names.