C++泛型编程友元模板的声明,该如何处理

C++泛型编程友元模板的声明

练习泛型编程,SNode是个双向迭代器,Rev是反向迭代器,我觉的可能是我的友元声明的有问题,麻烦各位看下:
#include <iostream>
#include <string>
using namespace std;

template <class T, class I> class Rev;
template<class P, class T>
P find(P start, P beyond, const T& x)
{
while(start != beyond && *start != x)
++start;
return start;
}

//一个链表和链表对应的迭代器

struct Node{
string content;
struct Node *next;
struct Node *pre;
};
//SNode是双向迭代器
class SNode {
public:
SNode(Node *p):pt(p){}
string& operator*()
{
if(!pt)
throw "pt is empty! can't *";
return pt->content;
}
SNode& operator++()
{
if(!pt)
throw "pt is empty! can't ++";
pt = pt->next;
}
SNode& operator--()
{
if(!pt)
throw "pt is empty! can't --";
pt = pt->pre;
}
friend bool operator==(const SNode&, const SNode&);
friend bool operator!=(const SNode&, const SNode&);
private:
Node *pt;
};

bool operator==(const SNode& right,const SNode& left)
{
return right.pt == left.pt;
}
bool operator!=(const SNode& right,const SNode& left)
{
return right.pt != left.pt;
}
//这是反向迭代适配器
template<class I,class T>
bool operator!=(const Rev<I,T>& right,const Rev<I,T>& left)
{
return right.pt == left.pt;
}
template<class I,class T>
bool operator!=(const Rev<I,T>& right,const Rev<I,T>& left)
{
return right.pt != left.pt;
}
template<class I,class T> class Rev {
friend bool operator==(const Rev<I,T>& right,const Rev<I,T>& left);
friend bool operator!=(const Rev<I,T>& right,const Rev<I,T>& left);
public:
Rev(){}
Rev(I i):pt(i){} //此处有问题
Rev<I,T>& operator++() {--pt; return *this;}
Rev<I,T>& operator--() {++pt; return *this;}
T* operator*() { I ret = pt; --ret; return *pt;}
private:
I pt;
};

int main()
{
Node t1,t2,t3;
t1.content = "zhang";
t2.content = "jing";
t3.content = "peng";
/*PNode
t1.next = &t2;
t2.next = &t3;
cout << *find(PNode(&t1),PNode(0),"jing");
*/
t1.next = &t2;
t2.pre = &t1;
t2.next = &t3;
t3.pre = &t2;
cout << *find(Rev<SNode,string>(&t3),Rev<SNode,string>(&t1),"jing");
}

我是在Ubuntu下面用g++编译的,希望各位能在自己的机子上试试

------解决方案--------------------
C/C++ code

//为下面模版函数ffun中的类参数声明模板类
template<typename T,typename T2> class C;    

//为模板类中的友元声明(声明了一个特化了的模版函数),声明模版函数
template<typename T,typename T2> void ffun(const class C<T,T2> &);    

//定义模板类
template<typename T,typename T2>
class C{
    //声明了一个特化了的模版函数,注意函数模版的特化(即特化定义)不同于特化模版函数的声明
    //friend void ffun<T,T2>(const C&);            //OK 方式一
    friend void ffun<>(const C<T,T2> &c);        //OK 方式二 (刚从上面的网友学的,以前真没这样用过)
    //friend void ffun<T,T2>(const C<T,T2>&);    //OK 方式三 这种方式也可以,在方式一的基础上显示指出C的类型
public:
    C(const T &t,const T2 &t2):i(t),a(t2){}
    void test(){
        std::cout<<"i:\t"<<i<<std::endl
                <<"a:\t"<<a<<std::endl;
    }
    bool operator==(const C &c1){
        return a==c1.a;
    }
    friend bool operator!=<>(const C<T,T2> &c1,const C<T,T2> &c2);
private:
    T i;
    T2 a;
};
//定义模版函数!!!!!!!!注意这是一个模版函数!!!!!!
template<typename T,typename T2>
void ffun(const C<T,T2> &c){
    std::cout<<"i:\t"<<c.i<<std::endl
            <<"a:\t"<<c.a<<std::endl;
}
////特化函数模版
//template<>
//void ffun<int,char>(const C<int,char> &c){
//    std::cout<<"i:\t"<<c.i<<std::endl
//            <<"a:\t"<<c.a<<std::endl;
//}
template<typename T,typename T2>
bool operator!=(const C<T,T2> &c1,const C<T,T2> &c2){
        return c2.a==c1.a;
}
int main(){
    C<std::string,char> c("123456789",'A');
    C<std::string,char> c1("789",'A');
    c.test();
    ffun(c);
    if(c==c1)
        std::cout<<"c==c1"<<std::endl;
    if(!(c!=c1))
        std::cout<<"c==c1 friend"<<std::endl;
    return 0;
}