大家帮我看看,使用模板时的一个函数未定义的问题

bad__ba 2009-11-26 10:04:03
#include< iostream >
using namespace std;

template< class T >
class ostream_iterator
{
public:
ostream_iterator( ostream & os, const char * s ):strm( & os ), str( s ){}
ostream_iterator & operator ++()
{
return * this;
}
ostream_iterator & operator ++( int )
{
return * this;
}
ostream_iterator & operator *()
{
return * this;
}
ostream_iterator & operator = ( const T & t )
{
* strm << t << str;
return * this;
}
private:
ostream * strm;
const char * str;
};

template< class T >
class istream_iterator
{
friend int operator == ( istream_iterator< T > & p, istream_iterator< T > & q );
public:
istream_iterator( istream & is ) : strm( & is ), full( 0 ), eof( 0 ){}
istream_iterator() : strm( 0 ), full( 0 ), eof( 1 ){}
istream_iterator & operator ++()
{
full = 0;
return * this;
}
istream_iterator operator ++( int )
{
istream_iterator r = * this;
full = 0;
return r;
}
T operator *()
{
fill();
return buffer;
}
private:
T buffer;
istream *strm;
int full;
int eof;
void fill()
{
if( ! full && ! eof )
{
if( * strm >> buffer )
{
full = 1;
}
else
{
eof = 1;
}
}
}
};

template< class T>
int operator == ( istream_iterator< T > & p, istream_iterator< T > & q )
{
if( p.eof && q.eof )
return 1;
if( ! p.eof && ! q.eof )
return( & p == & q );
p.fill();
q.fill();
return ( p.eof == q.eof );
}

template< class T >
int operator != ( istream_iterator< T > & p, istream_iterator< T > & q )
{
return !( p == q );
}

template< class P, class T >
void Copy( P start, P end, T t )
{
while( start != end )
{
* t ++ = * start ++;
}
}

int main( int argc, char * argv[] )
{
ostream_iterator< int > output ( cout, "\n" );
istream_iterator< int > input( cin );
istream_iterator< int > eof;

Copy( input, eof, output );
}

1>------ Rebuild All started: Project: testcpp, Configuration: Debug Win32 ------
1>Deleting intermediate and output files for project 'testcpp', configuration 'Debug|Win32'
1>Compiling...
1>test.cpp
1>Linking...
1>test.obj : error LNK2019: unresolved external symbol "int __cdecl operator==(class istream_iterator<int> &,class istream_iterator<int> &)" (??8@YAHAAV?$istream_iterator@H@@0@Z) referenced in function "int __cdecl operator!=<int>(class istream_iterator<int> &,class istream_iterator<int> &)" (??$?9H@@YAHAAV?$istream_iterator@H@@0@Z)
1>C:\Documents and Settings\zhao123\My Documents\Visual Studio 2008\Projects\testcpp\Debug\testcpp.exe : fatal error LNK1120: 1 unresolved externals
1>Build log was saved at "file://c:\Documents and Settings\zhao123\My Documents\Visual Studio 2008\Projects\testcpp\testcpp\Debug\BuildLog.htm"
1>testcpp - 2 error(s), 0 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
有两个问题想请教
第一个就是上面警告说的那里
	ostream_iterator & operator ++( int )
{
return * this;
}

这里返回值类型应该是一个ostream_iterator啊,那函数定义时候的ostream_iterator& 怎么理解?
第二个问题就是
unresolved external symbol "int __cdecl operator==(class istream_iterator<int> &,class istream_iterator<int> &)" (??8@YAHAAV?$istream_iterator@H@@0@Z) referenced in function "int __cdecl operator!=<int>(class istream_iterator<int> &,class istream_iterator<int> &)" (??$?9H@@YAHAAV?$istream_iterator@H@@0@Z)
我上面已经定义了==号了,为什么链接的时候又说没有这个符号的定义呢?
...全文
369 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
bad__ba 2009-11-27
  • 打赏
  • 举报
回复
是声名
bad__ba 2009-11-27
  • 打赏
  • 举报
回复
我试了一下,应该是使用模板时,友元函数定义的形式不对,不应是这样:
friend int operator == ( istream_iterator< T > & p, istream_iterator< T > & q );

而应该在函数名后面加<>,像下面这样:
friend int operator == < T > ( istream_iterator< T > & p, istream_iterator< T > & q );
  • 打赏
  • 举报
回复
我来告诉你最基本的原因
因为c++中,有个关键字 ostream_iterator,你的重名了,所以可能出错
  • 打赏
  • 举报
回复
#include< iostream >
using namespace std;

template< class T >
class ostream_iterator
{
public:
ostream_iterator( ostream & os, const char * s ): strm( & os ), str( s ) {}
ostream_iterator & operator ++()
{
return * this;
}
ostream_iterator & operator ++( int )
{
return * this;
}
ostream_iterator & operator *()
{
return * this;
}
ostream_iterator & operator = ( const T & t )
{
* strm << t << str;
return * this;
}
private:
ostream * strm;
const char * str;
};

template< class T >
class istream_iterator
{
friend int operator == <>( istream_iterator< T > & p, istream_iterator< T > & q );
public:
istream_iterator( istream & is ) : strm( & is ), full( 0 ), eof( 0 ) {}
istream_iterator() : strm( 0 ), full( 0 ), eof( 1 ) {}
istream_iterator & operator ++()
{
full = 0;
return * this;
}
istream_iterator operator ++( int )
{
istream_iterator r = * this;
full = 0;
return r;
}
T operator *()
{
fill();
return buffer;
}
private:
T buffer;
istream *strm;
int full;
int eof;
void fill()
{
if ( ! full && ! eof )
{
if ( * strm >> buffer )
{
full = 1;
}
else
{
eof = 1;
}
}
}
};

template< class T>
int operator == ( istream_iterator< T > & p, istream_iterator< T > & q )
{
if ( p.eof && q.eof )
return 1;

if ( ! p.eof && ! q.eof )
return( & p == & q );

p.fill();
q.fill();
return ( p.eof == q.eof );
}

template< class T >
int operator != ( istream_iterator< T > & p, istream_iterator< T > & q )
{
return !( p == q );
}

template< class P, class T >
void Copy( P start, P end, T t )
{
while ( start != end )
{
*( t++ ) = *( start++ );
}
}

int main( int argc, char * argv[] )
{
ostream_iterator< int > output ( cout, "\n" );
istream_iterator< int > input( cin );
istream_iterator< int > eof;

Copy( input, eof, output );
}
  • 打赏
  • 举报
回复
将operator==的实现放到 class里面你写friend的地方吧。
模板的友元函数不是这么写的
guolihui112 2009-11-26
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 namelij 的回复:]
我来告诉你最基本的原因
因为c++中,有个关键字 ostream_iterator,你的重名了,所以可能出错
[/Quote]

楼上说的不对 ,楼主有没有包含 ostream_iterator 的头文件,这不是问题所在。

主要是模板不是宏,宏的定义里可以包含前面没有声明的函数或变量。
模板必须声明。

1. istream_iterator 里用到了 operaotr == 函数,这个函数前边必须声明。
2. 若将 operator === 函数声明放到 istream_iterator 定义前。因为 operator == 函数又用到了 istream_iterator 类,所以还要在 operator == 前添加 istream_iterator 的前向声明

所以楼主的代码改动有二:
1. 在 istream_iterator 前添加如下两个声明:


template <class T> class istream_iterator;

template< class T>
int operator == ( istream_iterator< T > & p, istream_iterator< T > & q );



2. 因为 operator == 是模板函数, 所以将 istream_iterator 的 friend 声明改为如下:


friend int operator == <T> ( istream_iterator< T > & p, istream_iterator< T > & q );



附上 gcc 的链接错误,可以清楚的看到什么错误了(行号可能与楼主代码有出入):

tpl.cpp:36: warning: friend declaration 'int operator==(istream_iterator<T>&,
istream_iterator<T>&)' declares a non-template function

tpl.cpp:36: note: (if this is not what you intended, make sure the function temp
late has already been declared and add <> after the function name here)

C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccjFsnr7.o:tpl.cpp:(.text$_ZneIiEiR19istre
am_iteratorIT_ES3_[int operator!=<int>(istream_iterator<int>&, istream_ite
rator<int>&)]+0x14): undefined reference to `operator==(istream_iterator<int>
&, istream_iterator<int>&)'
collect2: ld returned 1 exit status

看第一行,

64,648

社区成员

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

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