2010-12-07 56 views
0

我想在模板BSTree.h中创建两个重载操作符,并且遇到了错误,它们确实不会告诉我问题是什么。单独或联合运行错误代码的搜索没有为我带来任何东西。无法声明2个朋友重载<<在模板中.h

第一个重载< <为BSTree不会导致编译任何错误,但第二次超载< <我为我的节点结构建立保持返回以下错误:

错误C4430:缺少类型说明符 - 假设为int。注意:C++不支持默认int
错误C2143:语法错误:缺少“”前‘*’

#ifndef BSTREE_H 
#define BSTREE_H 

#include <iostream> 
#include <fstream> 

template <typename T> 
class BSTree{ 

friend ostream& operator<<(ostream&, const BSTree<T>&); 

public: 
    BSTree(); 
    //BSTree(const BSTree &); 
    ~BSTree(); 

    void buildTree(ifstream&); 
    void setType(char); 
    bool getType(char); 

    bool insert(T*); 

    bool isEmpty(); 


private: 
    char type; 

    struct Node{ 
     T* data; 

     //subnode[0] == left subtree 
     //subnode[1] == right subtree 
     Node* subnode[2]; 
    }; 

    Node* head; 
    void destructorHelper(Node* &); 
    bool insertHelper(T*, Node* &); 
    friend ostream& operator<<(ostream&, const Node*&); 

}; 

编译器说,发生在这里的节点超载< <代码行中的错误。

template <typename T> 
ostream& operator<<(ostream &output, const BSTree<T> &out) { 
    if(head != NULL) 
     output << head; 
    return output; 
} 

template <typename T> 
ostream& operator<<(ostream &output, const Node* &out) { 
    if(out != NULL){ 
     output << out->subnode[0]; 
     output << *out->data; 
     output << out->subnode[1]; 
    } 

    return output; 
} 

不允许我宣布2重载< <在同.H即使它们是不同的对象?或者我在我的代码中搞了些什么?

回答

2

error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

通常这意味着,编译器不知道的标识作为一种类型,如此这般假设它是一个参数的名字,用类型隐含为int。 (在旧的C存在,在一个参数类型的int可以省略的规则。)这样的代码

void foo(bar); 

可能会发出此,如果编译器不知道类型bar并假定void foo(int bar)

template <typename T> 
std::ostream& operator<<(std::ostream &output, const typename BSTree<T>::Node* &out) 
{ 
    // ... 
} 

应该编译。 (请注意资格std::BSTree::。)

+0

这部分的工作,这样做只是常量BSTree ::节点*返回C4346错误。我不得不做const const typename :: BSTree ::节点*出来让错误消失 – Moniker 2010-12-07 19:28:08

0

也许你需要这个:

常量BSTree ::节点* &出

节点是内部结构。

0

我怀疑问题是ostream不在您的operator<<()朋友函数声明时的范围内。

要么添加using std::ostream;只是内部class BSTree{,或指定完全限定typenames:

friend std::ostream& operator<<(std::ostream&, const BSTree<T>&); 
... 
friend std::ostream& operator<<(std::ostream&, const Node*&); 

无论哪种方式,这些功能的实际定义将需要类似的改变。无论你做什么,都不要在文件范围的头文件中试图使用using std::ostream;或(更糟糕的)using namespace std;,因为它会影响翻译单元中的每个后续声明。

1

你必须在你的代码的几个误区:

  • 你需要添加<>后声明成为朋友
  • 即使你的朋友一个函数体是函数名,你需要指定你调用方法的对象。请记住,函数不会绑定到实例。在过去的原型
  • ,节点不可到达它定义的类之外,你必须精确BSTree ::节点