C++模板友元类

4
我正在尝试用c++编写一个2-3-4树的实现。因为已经有一段时间没有使用模板了,所以我遇到了一些错误。下面是我的极其基础的代码框架:
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;
}

主要代码文件是 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();
}

当我尝试从命令行编译时,使用以下命令: g++ main.cpp node.cpp TwoThreeFourTree.cpp 我得到了以下错误:
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  

我的主要问题是它为什么说"error: ‘TwoThreeFourTree’不是一个模板"。有人有什么想法吗?提前感谢所有的建议/帮助... 丹

完全重复 - 请参见https://dev59.com/D3VC5IYBdhLWcg3wtzkQ - Pavel Minaev
现在看起来并不完全是一个“确切”的重复,对吧? - danwoods
1
@Pavel:不是完全重复,这里的用户不想让模板的所有实例都有访问权限,而是只想让具有相同特定类型的实例具有访问权限。TwoThreeFourTree<int> 应该可以访问 TreeNode<int>,但不一定能访问 TreeNode<double> - David Rodríguez - dribeas
看起来除了TwoThreeFourTree之外,没有其他东西可以使用TreeNode,或者应该看到它;为什么不将节点类型作为树类的私有嵌套非模板类呢? - CTMacUser
2个回答

9
已接受的解决方案存在一个小问题,即将您的类打开到任何TwoThreeFourTree模板的实例化,而不仅仅是共享相同实例化类型的实例化。
如果您只想将类打开给相同类型的实例化,可以使用以下语法:
template <typename T> class TwoThreeFourTree; // forward declare the other template
template <typename T>
class TreeNode {
   friend class TwoThreeFourTree<T>;
   // ...
};
template <typename T>
class TwoThreeFourTree {
   // ...
};

谢谢,我没意识到需要进行前向声明才能使它工作!谢谢!!! :) - leetNightshade

5

当您使用friend关键字时,只需要将其声明为模板即可。您在代码中使用的友元声明语法不正确。您想要编写的是:

template <class U> friend class TwoThreeFourTree;

谢谢Charles Salvia,那效果很完美!现在要弄清楚,“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'... - danwoods
1
原始代码的意图与修改后代码的语义有细微的差别:在这里,您声明了所有实例化的TwoThreeFourTree(使用任何类型U)为友元,因此TwoThreeFourTree <int>可以访问 TreeNode <double> - David Rodríguez - dribeas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接