0

I'm working on a binary search tree class and implementing a Find operation. There are two versions of the public function, one which returns a const Node* and is const and the other which returns a non-const Node* and is not itself const. Here are the public definitions:

const Node *Find(const T &t) const { Find(t, m_root); }

Node *Find(const T &t) { Find(t, m_root); }

And here's the definition of the private Find method:

template <typename T>
const Node* CTree<T>::Find(const T &t, Node *root) const {
    if (root == 0)
        return Node();
    else if (t < root->m_number)
        Find(t, root->m_ll);
    else if (t > root->m_number)
        Find(t, root->m_rl);
    else
        return this;
}

Visual Studio is telling me that "'Find' : member function not declared in 'CTree'". Why would it say that?

Edit to add specifics of error messages: There are 5 messages for the line of the private method definition starting const Node*...

Missing type specifier - int assumed

Syntax error : missing ';' before '*'

'T' : undeclared identifier

'CTree' : 'T' is not a valid template type argument for parameter 'T'

syntax error : missing ',' before '&'

Then one more error for the closing brace of the definition (this is the one that I believe is causing the other 5):

'Find' : member function not declared in 'CTree'

As a note, Visual Studio is not highlighting Node in the definition of Find as it does elsewhere.

Here's the whole class: http://pastebin.com/JEEZJD4n

spartanhooah
  • 183
  • 4
  • 15

1 Answers1

1

Mistake is in method definition (line 93 of pastebin):

template <typename T>
const Node* CTree<T>::Find(const T &t, Node *root) const {

You don't have any type Node in global scope, because your class Node in nested. So first fix will be an addition of the parent class qualification:

template <typename T>
const CTree<T>::Node* CTree<T>::Find(const T &t, Node *root) const {

But, there is another problem: now, compiler cannot parse it right way. You must add typename keyword, to indicate a nested type:

template <typename T>
const typename CTree<T>::Node* CTree<T>::Find(const T &t, Node *root) const {

See "When is the “typename” keyword necessary?" for details.

Notes:

  • You can avoid any of those problems if you put method definition directly to a class body (depending on your code style).
  • You could broadly enrich your coding experience, and make your template coding more productive, if you could use different compilers. Note how g++ is clearer in this kind of error:

    main.cpp : At global scope :
    main.cpp : 104 : 7 : error : 'Node' does not name a type
    const Node* CTree<T>::Find(const T &t, Node *root) const
          ^
    
    main.cpp: At global scope:
    main.cpp:104:7: error: need 'typename' before 'CTree<T>::Node' 
    because 'CTree<T>' is a dependent scope
    const CTree<T>::Node* CTree<T>::Find(const T &t, Node *root) const
          ^
    
Community
  • 1
  • 1
Ivan Aksamentov - Drop
  • 12,860
  • 3
  • 34
  • 61
  • Thanks for the help. In my first two C++ classes, I was taught to split the declarations and definitions in general. I've learned about templated functions and classes, but this is my first encounter with a nested class. – spartanhooah Feb 16 '14 at 20:36