"X不是Y的成员"尽管X是Y的朋友?

use*_*138 2 c++ templates

我正在尝试编写二叉树.为什么以下代码报告错误C2039,"'<<':不是'btree <T>'的成员",即使<<运算符已被声明为btree类中的友元函数?

#include<iostream>
using namespace std;

template<class T>
class btree
{
public:
    friend ostream& operator<<(ostream &,T);
};

template<class T>
ostream& btree<T>::operator<<(ostream &o,T s)
{
    o<<s.i<<'\t'<<s.n;
    return o;
}
Run Code Online (Sandbox Code Playgroud)

Jam*_*nze 7

template <typename T>
class BTree
{
    //  ...
    friend std::ostream& operator<<( std::ostream&, T );
    //  ...
};
Run Code Online (Sandbox Code Playgroud)

你告诉编译器有一个非模板自由函数

std::ostream& operator<<( std::ostream&, Type )
Run Code Online (Sandbox Code Playgroud)

对于你碰巧实例化BTree的任何类型.但是你永远不会提供这样的功能.您提供的定义是针对成员的,但作为成员函数,您operator<<需要的参数太多.

鉴于这BTree是一种通用类型,它不应该提供显示其包含的元素的方法; 这取决于所包含的元素类型.有意义的是:

template <typename T>
class BTree
{
    struct Node
    {
        //  ...
        void display( std::ostream& dest, int indent ) const;
    };

    //  ...
    void display( std::ostream& dest ) const;
    friend std::ostream& operator<<( std::ostream& dest, BTree const& tree )
    {
        tree.display( dest );
        return dest;
    }
};

template <typename T>
void BTree::display( std::ostream& dest ) const
{
    if ( myRoot == NULL ) {
        dest << "empty";
    } else {
        myRoot->display( dest, 0 );
    }
}

template <typename T>
void BTree::Node::display( std::ostream& dest, int indent ) const
{
    dest << std::string( indent, ' ' ) << data;
    if ( myLeft != NULL ) {
        myLeft->display( dest, indent + 2 );
    }
    if ( myRight != NULL ) {
        myRight->display( dest, indent + 2 );
    }
}
Run Code Online (Sandbox Code Playgroud)