4

I'm trying to write an implementation of a 2-3-4 tree in c++. I'm it's been a while since I've used templates, and I'm getting some errors. Here's my extremely basic code framework:
node.h:

    #ifndef TTFNODE_H  
    #define TTFNODE_H  
    template <class T>  
    class TreeNode  
    {  
      private:  
      TreeNode();  
      TreeNode(T item);  
      T data[3];  
      TreeNode<T>* child[4];  
      friend class TwoThreeFourTree<T>;   
      int nodeType;  
    };  
    #endif

node.cpp:

#include "node.h"

using namespace std;
template <class T>
//default constructor
TreeNode<T>::TreeNode(){
}

template <class T>
//paramerter receving constructor
TreeNode<T>::TreeNode(T item){
data[0] = item;
nodeType = 2;
}

TwoThreeFourTree.h

#include "node.h"
#ifndef TWO_H
#define TWO_H
enum result {same, leaf,lchild,lmchild,rmchild, rchild};
template <class T> class TwoThreeFourTree
{
  public:
    TwoThreeFourTree();

  private:
    TreeNode<T> * root;
};
#endif

TwoThreeFourTree.cpp:

#include "TwoThreeFourTree.h"
#include <iostream>
#include <string>

using namespace std;

template <class T>
TwoThreeFourTree<T>::TwoThreeFourTree(){
  root = NULL;
}

And main.cpp:

#include "TwoThreeFourTree.h"
#include <string>
#include <iostream>
#include <fstream>

using namespace std;

int main(){
  ifstream inFile;
  string filename = "numbers.txt";
  inFile.open (filename.c_str());
  int curInt = 0;
  TwoThreeFourTree <TreeNode> Tree;

  while(!inFile.eof()){
    inFile >> curInt;
    cout << curInt << " " << endl;
  }

  inFile.close();
}

And when I try to compile from the command line with: g++ main.cpp node.cpp TwoThreeFourTree.cpp

I get the following errors:

In file included from TwoThreeFourTree.h:1,  
             from main.cpp:1:  
node.h:12: error: ‘TwoThreeFourTree’ is not a template  
main.cpp: In function ‘int main()’:  
main.cpp:13: error: type/value mismatch at argument 1 in template parameter list for ‘template<class T> class TwoThreeFourTree’  
main.cpp:13: error:   expected a type, got ‘TreeNode’  
main.cpp:13: error: invalid type in declaration before ‘;’ token  
In file included from node.cpp:1:  
node.h:12: error: ‘TwoThreeFourTree’ is not a template  
In file included from TwoThreeFourTree.h:1,  
             from TwoThreeFourTree.cpp:1:  
node.h:12: error: ‘TwoThreeFourTree’ is not a template  

My main question is why it's saying "error: ‘TwoThreeFourTree’ is not a template". Does anyone have any ideas? Thanks for all advice/help in advance... Dan

int3
  • 12,861
  • 8
  • 51
  • 80
danwoods
  • 4,889
  • 11
  • 62
  • 90
  • Exact dupe - see http://stackoverflow.com/questions/206045/how-do-you-mark-a-struct-template-as-friend – Pavel Minaev Nov 27 '09 at 20:53
  • Not quite an, "exact" dupe, now is it? – danwoods Nov 27 '09 at 21:33
  • 1
    @Pavel: Not an exact duplicate, here the user does not want all instantiations of the template to have access but rather only instantiations with the same particular type. A `TwoThreeFourTree` should have access to `TreeNode` but not necessarily to `TreeNode` – David Rodríguez - dribeas Nov 28 '09 at 13:01
  • It looks like nothing else besides `TwoThreeFourTree` can use `TreeNode`, or should see it; why not just make the node type a `private` nested non-template class of the tree class? – CTMacUser Mar 28 '12 at 19:42

2 Answers2

9

The solution that has been accepted has the slight problem of opening your class to any instantiation of the TwoThreeFourTree template, not only those that share the same instantiation type.

If you only want to open the class to instantiations of the same type you can use the following syntax:

template <typename T> class TwoThreeFourTree; // forward declare the other template
template <typename T>
class TreeNode {
   friend class TwoThreeFourTree<T>;
   // ...
};
template <typename T>
class TwoThreeFourTree {
   // ...
};
David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
5

You just need to declare it as a template when you use the friend keyword. You're using incorrect syntax for a friend declaration in your code. What you want to write is:

template <class U> friend class TwoThreeFourTree;
Charles Salvia
  • 52,325
  • 13
  • 128
  • 140
  • Thanks Charles Salvia, that worked perfect! Now to figure out, "main.cpp:13: error: type/value mismatch at argument 1 in template parameter list for ‘template class TwoThreeFourTree’ main.cpp:13: error: expected a type, got ‘TreeNode'... – danwoods Nov 27 '09 at 21:40
  • 1
    There is a slight difference between the intention in the original code and the semantics in the modified code: here you are declaring all instantiations of `TwoThreeFourTree` (with any type U) as friends, and thus `TwoThreeFourTree` has access to `TreeNode' – David Rodríguez - dribeas Nov 28 '09 at 12:36