2009-11-27 6 views
4

J'essaye d'écrire une implémentation d'un arbre 2-3-4 en C++. Ça fait un moment que j'ai utilisé des templates, et j'ai quelques erreurs. Voici mon cadre de code extrêmement basique:
node.h:C++ classe d'amis basée sur un modèle

#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; 
} 

Et 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(); 
} 

Et quand je tente de compiler à partir de la ligne de commande avec: g ++ main.cpp node.cpp TwoThreeFourTree.cpp

Je reçois les erreurs suivantes:

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 

Ma question principale est pourquoi il dit "erreur:" TwoThreeFourTree "n'est pas un modèle". Quelqu'un a-t-il une idée? Merci pour tout conseil/aide à l'avance ... Dan

+0

duper Exact - voir http://stackoverflow.com/questions/206045/how-do -you-marque-un-struct-template-as-friend –

+0

Pas tout à fait un, "exact" dupe, maintenant c'est? – danwoods

+1

@Pavel: Ce n'est pas une copie exacte, ici l'utilisateur ne veut pas que toutes les instanciations du template aient accès mais seulement des instanciations avec le même type particulier. Un 'TwoThreeFourTree ' devrait avoir accès à 'TreeNode ' mais pas nécessairement 'TreeNode ' –

Répondre

5

Vous avez juste besoin de le déclarer comme un modèle lorsque vous utilisez le mot-clé ami. Vous utilisez une syntaxe incorrecte pour une déclaration d'ami dans votre code. Qu'est-ce que vous voulez écrire est:

template <class U> friend class TwoThreeFourTree; 
+0

Merci Charles Salvia, ça a fonctionné parfaitement! Maintenant, pour comprendre, "erreur main.cpp: 13: type/valeur discordance à l'argument 1 dans la liste des paramètres de modèle pour 'modèle classe TwoThreeFourTree' main.cpp: 13: erreur: attendu un type, a reçu 'TreeNode' .. – danwoods

+1

Il y a une légère différence entre l'intention dans le code original et la sémantique dans le code modifié: ici vous déclarez toutes les instanciations de 'TwoThreeFourTree' (avec n'importe quel type U) comme amis, et donc' TwoThreeFourTree 'a accès à 'TreeNode ' –

7

La solution qui a été acceptée a le léger problème de l'ouverture de votre classe à une instanciation du modèle TwoThreeFourTree, non seulement ceux qui partagent le même type d'instanciation.

Si vous ne souhaitez que d'ouvrir la classe à instanciation du même type que vous pouvez utiliser la syntaxe suivante:

template <typename T> class TwoThreeFourTree; // forward declare the other template 
template <typename T> 
class TreeNode { 
    friend class TwoThreeFourTree<T>; 
    // ... 
}; 
template <typename T> 
class TwoThreeFourTree { 
    // ... 
}; 
+0

Merci, je ne savais pas que je devais faire une déclaration avant de le faire fonctionner! Merci !!! :) – leetNightshade

Questions connexes