| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 709 人关注过本帖
标题:把友元函数的实现写到类的外面去时出现了问题
只看楼主 加入收藏
thlgood
Rank: 5Rank: 5
等 级:职业侠客
帖 子:281
专家分:381
注 册:2010-9-24
结帖率:91.43%
收藏
已结贴  问题点数:20 回复次数:2 
把友元函数的实现写到类的外面去时出现了问题
楼主的程序是这样的
我定义了一个类模板,类模板里面的有一个结构体node:

现在这个类有一个友元函数travels(),当我把这个函数的实现写在类的内部的时候能够正常编译,但是当我把它的实现写到内的外部的时候出现了语法错误

程序代码:
template<typename T>
class rbtree
{
private:
    struct node
    {
        T m_value;    //node也要用到T
        ...
    };
    ...
public:
    ...
    //先序打印红黑树
    friend void travels(rbtree<T>::node* root)
    {
        if (NULL != root)
        {
            //递归调用
            if (NULL != root->m_left) travels(root->m_left);
            cout << root->m_value << endl;
            if (NULL != root->m_right) travels(root->m_right);
        }
    }
};


现在我面临的问题是,如果把友元函数travels()的实现写到类的外面去?
我是这样写的,但是不正确啊
程序代码:
template<typename T>
void travels(rbtree<T>::node* rt)
{
    rbtree::node* r = rt;
    if (r != NULL)
    {
        if(NULL != r->m_left) travels(r->m_left);
        cout << r->m_value << endl;
        if(NULL != r->m_right)travels(r->m_right);
    }
}

语法错误为:
程序代码:
rbTree.cpp:37:47: 警告:友元声明‘void travels(rbtree<T>::node*)’声明了一个非模板函数 [-Wnon-template-friend]
     friend void travels(rbtree<T>::node* rt);
                                               ^
rbTree.cpp:37:47: 附注:(如果这不是您原来的想法,请确定此函数模板已经声明过,并在这里的函数名后面添加 <>)
rbTree.cpp:147:28: 错误:变量或字段‘travels’声明为 void

 void travels(rbtree<T>::node* rt)
                            ^
rbTree.cpp:147:34: 错误:‘rt’在此作用域中尚未声明

 void travels(rbtree<T>::node* rt)


谢谢关注
搜索更多相关主题的帖子: 函数 结构体 color 
2013-05-08 17:11
thlgood
Rank: 5Rank: 5
等 级:职业侠客
帖 子:281
专家分:381
注 册:2010-9-24
收藏
得分:0 
楼上的代码是简化过的代码,如果你觉的我在1L阐述得不够清晰,可以看看完整的代码:
程序代码:
#include <iostream>
#include <queue>
using namespace std;

template<typename T>
class rbtree
{
private:
    enum{RED, BLACK};
    struct node
    {
        T     m_value;
        node* m_left;
        node* m_right;
        node* m_parent;
        int   m_color;

        node(T& value, node* left = NULL, node* right = NULL , 
             node* parent = NULL):
             m_value(value), m_left(left), 
             m_right(right), m_parent(parent),
             m_color(BLACK)
        {}
    };

    node* root;
    rbtree(rbtree& rhs);
    rbtree& operator=(rbtree& rhs);
public:
    rbtree(T& value)
    {root = new node(value);}
    rbtree():root(NULL){}

    //insert a value to red black tree
    void insert(T& value);
    //left-middle-right travel
    friend void lmr_travel(rbtree<T>::node* rt);
    //midle-left-right travel
//    friend void mlr_travel(rbTree<T>::node*);
    //destroy this tree
    void destroy();

    ~rbtree();
};

template<typename T>
void rbtree<T>::insert(T& value)
{
    if (NULL == root)
    {
        root = new node(value);
        return;
    }

    enum{LEFT, RIGHT};
    int positon = LEFT;
    node* nodep = root;
    while(true)
    {
        if (value > nodep->m_value)
        {
            if (NULL != nodep->m_right)
            {
                nodep = nodep->m_right;
                continue;
            }
            positon = RIGHT;
            break;
        }
        else if (value < nodep->m_value)
        {
            if (NULL != nodep->m_left)
            {
                nodep = nodep->m_left;
                continue;
            }
            positon = LEFT;
            break;
        }
        else
        {
            return;
        }
    }
    if (nodep->m_color = BLACK)
    {
        if (positon == LEFT)
        {
            nodep->m_left = new node(value);
            nodep->m_left->m_parent = nodep;
            nodep->m_left->m_color = RED;
        }
        else
        {
            nodep->m_right = new node(value);
            nodep->m_right->m_parent = nodep;
            nodep->m_right->m_color = RED;
        }
    }
}

template<typename T>
rbtree<T>::~rbtree()
{
    destroy();
}

template<typename T>
void rbtree<T>::destroy()
{
    queue<node *>rbqueue;
    rbqueue.push(root);
    node* tmp;
    while(!rbqueue.empty())
    {
        tmp = rbqueue.front();
        if (tmp != NULL)
        {
            if (NULL != tmp->m_left)
            {
                rbqueue.push(tmp->m_left);
            }
            if (NULL != tmp->m_right)
            {
                rbqueue.push(tmp->m_right);
            }
            delete tmp;
        }
        rbqueue.pop();
    }
    root = NULL;
}
/*
template<typename T>
void lmr_travel(rbtree<T>::node* rt)
{
    rbTree::node* r = rt;
    if (r != NULL)
    {
        help_travel(r->m_left);
        cout << r->value << endl;
        help_travel(r->m_right);
    }
}
*/
template<typename T>
void lmr_travel(rbtree<T>::node* rt)
{
    rbtree::node* r = rt;
    if (r != NULL)
    {
        if(NULL != r->m_left) 
            lmr_travel(r->m_left);
        cout << r->value << endl;
        if(NULL != r->m_right)
            lmr_travel(r->m_right);
    }
}
int main()
{
    rbtree<int> t;
    return 0;
}


[ 本帖最后由 thlgood 于 2013-5-8 17:14 编辑 ]

o(∩∩)Linux & Python 群:187367181
2013-05-08 17:13
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9031
专家分:54061
注 册:2011-1-18
收藏
得分:20 
你基础知识缺乏,有太多错误,我只能挑重要的讲一下

程序代码:
template<typename T>
class foo
{
private:
    struct node
    {
        T value;
    };
public:
    friend void bar( typename foo<T>::node* root )
    {
        root->value = 1;
    }
};
写在里面,这是定义了一个 友元普通函数

程序代码:
template<typename T>
class foo
{
private:
    struct node
    {
        T value;
    };
public:
    template<typename T> friend void bar( typename foo<T>::node* root );
};

template<typename T>
void bar( typename foo<T>::node* root )
{
    root->value = 1;
}
写在外面,这是定义了一个 友元模板函数
但此时,所有bar都是foo的友元,即bar<double>也会是foo<int>的友元,所以最正确的写法是
程序代码:
template<typename T> class foo;
template<typename T> void bar( typename foo<T>::node* root );

template<typename T>
class foo
{
private:
    struct node
    {
        T value;
    };
public:
    friend void bar<T>( typename foo<T>::node* root );
    friend int main();
};

template<typename T>
void bar( typename foo<T>::node* root )
{
    root->value = 1;
}

2013-05-09 09:11
快速回复:把友元函数的实现写到类的外面去时出现了问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.026715 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved