1

I have template class with a nested template class like this

#include <utility>
template<typename K> class Tree23 {

    public:
    template<typename Key> class Node {
       private:
        friend class Tree23<K>;             
        // snip . . .
    };  
    Node<K> root; 
 public:    
     // snip ...            
     std::pair<bool, Node<K> *> Search(K key);
};

I get several compile errors on the signature of the Search method implementation

template<typename K> 
std::pair<bool, Tree23<K>::Node<K> *> Tree23<K>::Search(K key)
{
    // make sure tree has at least one element    
    if (root == 0) {
          return std::make_pair(false, 0);

    } else {
          return Locate(key, root);
    }
}    

The errors correspond to the line

template<typename K> std::pair<bool, Tree23<K>::Node<K> *> Tree23<K>::Search(K key)

The complie errors are:

  Node.h:64:55: error: type/value mismatch at argument 2 in template parameter list for   'template<class _T1, class _T2> struct std::pair'    
  Node.h:64:55: error:   expected a type, got '(Tree23<K>::Node < <expression error>)'    
  Node.h:64:58: error: expected unqualified-id before '>' token    
  Node.h:64:58: error: expected initializer before '>' token

I'm unclear how to fix this. Any feedback would be appreciated.

Kurt Krueckeberg
  • 1,225
  • 10
  • 11

1 Answers1

2

Try this:

template<typename K> 
std::pair<bool, typename Tree23<K>::template Node<K> *> Tree23<K>::Search(K key)
//              ^^^^^^^^            ^^^^^^^^
{
    // make sure tree has at least one element
    if (root == 0) {
          return std::make_pair(false, 0);

    } else {
          return Locate(key, root);
    }
}

Also check this out as to why this is necessary.

Community
  • 1
  • 1
Fiktik
  • 1,941
  • 16
  • 25
  • Thanks for the reply. Adding **typename** resulted in a different set of errors: Node.h:64:67: error: template argument 2 is invalid Node.h:64:69: error: prototype for `int Tree23::Search(K)` does not match any in class `Tree23` Node.h:57:44: error: candidate is: `std::pair::Node*> Tree23::Search(K)` Somehow the complier now thinks the prototype is `int Tree23::Search(K)` – Kurt Krueckeberg Apr 29 '13 at 16:32
  • Thanks. I had mistakenly added only typename, like so `std::pair::Node *>`, instead of also adding template, like so `std::pair::template Node *>` – Kurt Krueckeberg Apr 29 '13 at 18:24
  • Adding a typedef to class Tree23, of `typedef Node nodeType;`, shortens the function signature to `template std::pair::nodeType *> Tree23::Search(K key) {//... }` – Kurt Krueckeberg Apr 29 '13 at 18:28
  • Do you really need the `Node` to be a template? You could just have a nested `class Node { ... };` in the `Tree23` template. Of course this would only work if you always have `Key` in the Node the same as `K` in the Tree. – Fiktik Apr 29 '13 at 18:33