关于模板类的问题,请大家帮忙看看

prince_of_ 2014-11-09 12:10:42
最近在写一个模板类,希望实现类似c#中List类的功能,我写的list类是基于node结构体的单链表模板类。
node定义如下
template< class anytype >
struct node
{
anytype value;
node* next; //指向下个结点
};
list类声明如下
template< class anytype >
class list
{
public:
list()
{
count = 0;
head.next = NULL;
}
~list()
int get_count()
{
return count;
}
void add();
void add( const anytype c );
void add( const anytype p[], int n );
void add( const int p[], char n, char current );
bool dlt( int i );
void go_through(); //遍历
bool insert( int i, const anytype c );
void clear();
anytype & operator [] ( int i );
int seek( const anytype model ); //返回值-1表示没找到
private:
node<anytype> head; //头结点,不用来存储数据
int count; //链表结点个数
};
我主要要解决add()函数的问题,第一个无参的add定义如下
template< class anytype >
void list<anytype>::add()
{
node<anytype>* p = &head;

while ( p -> next != NULL )
p = p -> next;

p -> next = new node<anytype>;
// p -> next -> value = c;
p -> next -> next = NULL;

count++;
}
无参的add()负责在链表尾部添加一个未赋值的结点(赋值语句被注释掉),add()可以处理任意维数的list类,比如list<int>和list< list<int> >,前者添加一个node<int>结点,后者添加一个node< list<int>结点,这样的话可以创建任意维数的对象,例如三维的list< list< list<int> > >可以作为三位数组来使用。但是通过这样的方式来定义多维数组比较慢,比如3*3的二维链表list< list<int> > a,
需要执行三次a.add()来添加三个一维链表,再分别执行a[1],a[2],a[3].add()各三次来添加三个int结点。我想通过
template< class anytype >
void list< anytype >::add( const int p[], char n, char current ) //p[]数组存储
//每维的结点数,比如p[] = { 4, 3 },表示二维四个结点,一维三个结点,相当于int[4][3]的数组
//n代表p的数组上限,也就是最大维数,current代表函数当前处理的维数,用于递归控制
{
if ( current >= 2 )
{
int number = p[n - current];

for ( int i = 1; i <= number; i++ )
{
add();
( operator [] ( i ) ).add( p, n, current - 1 );
}
}
else
{
int number = p[n - current];

for ( int i = 1; i <= number; i++ )
add();
}
}
operator[](i)函数返回链表中第i个结点的value值,对于二维链表list< list<int> > a,
a[1]就是一个list<int>类型的对象,比a要低一维,考虑到一维链表list<int> b无法执行b[i].add,所以判断当前维数不小于2为控制条件,可是系统报错
f:\c\test\diy.h(137) : error C2228: left of '.add' must have class/struct/union type
f:\c\test\diy.h(69) : while compiling class-template member function 'void __thiscall list<int>::add(const int [],char,char)'
我的理解是系统认为( operator [] ( i ) ),就是比当前对象低一维的对象不是结构体,而我做如下改动,就不会报错,但却没办法递归了
template< class anytype >
void list< anytype >::add( const int p[], char n, char current )
{
if ( current >= 2 )
{
int number = p[n - current];

for ( int i = 1; i <= number; i++ )
{
add();
( operator [] ( i ) ).add(/* p, n, current - 1*/);
}
}
else
{
int number = p[n - current];

for ( int i = 1; i <= number; i++ )
add();
}
}
我想可能是递归的使用让电脑无法判断( operator [] ( i ) )是否还是list对象,请问怎么解决这个问题,如果可以我很多问题都能迎刃而解?
...全文
235 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
bobo_包子 2014-11-11
  • 打赏
  • 举报
回复
我觉得你这个在c++11里面可以完美解决了,c++11里面有enable_if,这个可以满足你的要求了。
prince_of_ 2014-11-10
  • 打赏
  • 举报
回复
引用 1 楼 FancyMouse 的回复:
1. 把current给放成template int 2. 你这逻辑就有问题啊。current-1怎么能调用this->operator[]?
能把修改后的代码贴出来吗,template int是怎么弄?
bobo_包子 2014-11-09
  • 打赏
  • 举报
回复
你这个肯定不行,只能特化。或者如2楼
prince_of_ 2014-11-09
  • 打赏
  • 举报
回复
引用 2 楼 zhao4zhong1 的回复:
模板是语法糖。 语法糖越甜,编译调试查错越苦! 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中,我认为不值当。
引用 6 楼 bbs2241 的回复:
[quote=引用 4 楼 prince_of_ 的回复:] [quote=引用 1 楼 FancyMouse 的回复:] 1. 把current给放成template int 2. 你这逻辑就有问题啊。current-1怎么能调用this->operator[]?
我想问一下,对于三维的 list< list< list<int> > > a,( *this )[i]是第i个结点的value值就是一个list< list<int> >的二维对象,怎么在a的成员函数中调用a[i]的第j个结点的value值就是一个list<int>对象的add()函数,就是a[i][j].add(),看来通过this指针是有问题的。[/quote] 思路有问题,是模板实例化的时候出错了。你还没明白模板的实质,你再想想你这个add函数每个实例化是什么样子,你就明白了。[/quote]我也注意到了这点,对于普通类型,非list类、结构体、联合体以及普通数据类型,用简单的p -> next -> value = c;就可以完成赋值,可是list对象并不能这样处理,受到了链表储存结构的影响,这样确实导致了数据类型的差别,违背了模板与数据类型无关的初衷,请问怎么实现链表的储存结构与类型完全分离呢?
prince_of_ 2014-11-09
  • 打赏
  • 举报
回复
引用 5 楼 FENGQIYUNRAN 的回复:
楼主想法很好,一定能解决
谢谢支持
赵4老师 2014-11-09
  • 打赏
  • 举报
回复
模板是语法糖。 语法糖越甜,编译调试查错越苦! 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中,我认为不值当。
bobo_包子 2014-11-09
  • 打赏
  • 举报
回复
引用 4 楼 prince_of_ 的回复:
[quote=引用 1 楼 FancyMouse 的回复:] 1. 把current给放成template int 2. 你这逻辑就有问题啊。current-1怎么能调用this->operator[]?
我想问一下,对于三维的 list< list< list<int> > > a,( *this )[i]是第i个结点的value值就是一个list< list<int> >的二维对象,怎么在a的成员函数中调用a[i]的第j个结点的value值就是一个list<int>对象的add()函数,就是a[i][j].add(),看来通过this指针是有问题的。[/quote] 思路有问题,是模板实例化的时候出错了。你还没明白模板的实质,你再想想你这个add函数每个实例化是什么样子,你就明白了。
FancyMouse 2014-11-09
  • 打赏
  • 举报
回复
1. 把current给放成template int 2. 你这逻辑就有问题啊。current-1怎么能调用this->operator[]?
FeelTouch Labs 2014-11-09
  • 打赏
  • 举报
回复
楼主想法很好,一定能解决
prince_of_ 2014-11-09
  • 打赏
  • 举报
回复
引用 1 楼 FancyMouse 的回复:
1. 把current给放成template int 2. 你这逻辑就有问题啊。current-1怎么能调用this->operator[]?
我想问一下,对于三维的 list< list< list<int> > > a,( *this )[i]是第i个结点的value值就是一个list< list<int> >的二维对象,怎么在a的成员函数中调用a[i]的第j个结点的value值就是一个list<int>对象的add()函数,就是a[i][j].add(),看来通过this指针是有问题的。

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧