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++编译的,希望各位能在自己的机子上试试
------解决方案--------------------
练习泛型编程,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; }