 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
fabio de francesco Guest
|
Posted: Thu Jun 24, 2004 6:18 pm Post subject: errors = templates * friends; |
|
|
Hello,
I'm just joking with the Subject, but I really don't know how to make
a synthesis of two questions about some code I'm trying to write.
In the following I post this little code, with "..." meaning what I
think can be omitted for brevity.
// file database.h
....
template <typename T>
class DataBase
{
public:
DataBase();
...
private:
...
void run();
ostream& print( ostream & );
friend ostream& operator<<(ostream &out, DataBase
{ return db.print( out ); }
};
....
// file database.cpp
....
template <typename T>
DataBase<T>::DataBase()
{...}
template<typename T>
void DataBase<T>::run()
{...}
....
// file usedb.cpp
....
#include "database.h"
#include "person.h"
....
int main()
{
DataBase<Person> db; // usedb.cpp:11 (error)
...
return 0;
}
The first problem is that the linker editor ( I suppose ) comes out
with this error:
/database/src/usedb.cpp:11: undefined reference to
`DataBase<Person>::DataBase[in-charge]()'
I got the same error also if I try to instantiate 'DataBase<int> db'.
This is not the first time I use templates but I've never seen such an
error.
I'm sure I am doing some stupid thing.
The second problem arises if I try to extract the implementation code
of the friend overloaded operator "<<" from the class definition (
database.h ) to be put in the implementation file ( database.cpp ).
// file DataBase.h
....
friend ostream& operator<<( ostream &out, DataBase
....
// file DataBase.cpp
....
template<typename T>
ostream& operator<<( ostream &out, DataBase
{ return db.print( out ); }
....
Here the errors, while compiling:
/src/database.h:31: warning: friend declaration `std::ostream&
operator<<(std::ostream&, DataBase
function
/src/database.h:31: warning: (if this is not what you intended, make
sure the function template has already been declared and add <> after
the function name here) -Wno-non-template-friend disables this warning
That's all. I want to thank in advance everyone who will explain what
kind of errors I put in the code. I would appreciate also any partial
reply on the first topic that is the most important for me.
Ciao,
Fabio De Francesco.
|
|
| Back to top |
|
 |
Rob Williscroft Guest
|
Posted: Thu Jun 24, 2004 6:42 pm Post subject: Re: errors = templates * friends; |
|
|
fabio de francesco wrote in
news:ba2f9c57.0406241018.182ef25a (AT) posting (DOT) google.com in comp.lang.c++:
| Quote: | Hello,
I'm just joking with the Subject, but I really don't know how to make
a synthesis of two questions about some code I'm trying to write.
In the following I post this little code, with "..." meaning what I
think can be omitted for brevity.
// file database.h
...
template <typename T
class DataBase
{
public:
DataBase();
...
private:
...
void run();
ostream& print( ostream & );
|
This is a non-template function, you can't define it outside of the
class-template, as you try to do later.
| Quote: | friend ostream& operator<<(ostream &out, DataBase
{ return db.print( out ); }
};
...
|
Here's your first problem, templates need to be defined in the
the same compilation that uses them, put these defenition's in
your header file.
| Quote: | // file database.cpp
...
template <typename T
DataBase
{...}
template<typename T
void DataBase
{...}
...
[snip] |
Here's an example of a template friend (note all the cruft):
#include <iostream>
#include <ostream>
/* Forward declare X, so we can forward declare operator <<
*/
template < typename T > struct X;
template < typename T >
std::ostream & operator << ( std::ostream &os, X< T > const & );
template < typename T >
struct X
{
friend /* Note the <> */
std::ostream & operator << <>( std::ostream &os, X< T > const & );
};
/* declaration/defenition - in the *header*
*/
template < typename T >
std::ostream & operator << ( std::ostream &os, X< T > const & )
{
os << "friendn";
return os;
}
int main()
{
X< int > x;
std::cout << x;
}
Alternativly do it like this:
#include
#include <ostream>
template < typename T >
struct X
{
private:
void printon( std::ostream &os ) const;
friend std::ostream & operator << ( std::ostream &os, X< T > const &x )
{
x.printon( os );
return os;
}
};
template < typename T >
void X< T >::printon( std::ostream &os ) const
{
os << "friendn";
}
int main()
{
X< int > x;
std::cout << x;
}
Slightly less cruft .
Rob.
--
http://www.victim-prime.dsl.pipex.com/
|
|
| Back to top |
|
 |
John Harrison Guest
|
Posted: Thu Jun 24, 2004 9:47 pm Post subject: Re: errors = templates * friends; |
|
|
| Quote: |
Here's an example of a template friend (note all the cruft):
#include <iostream
#include
/* Forward declare X, so we can forward declare operator
*/
template < typename T > struct X;
template < typename T
std::ostream & operator << ( std::ostream &os, X< T > const & );
|
This confuses me, I know what to do but I still don't understand why.
Why is it necessary to forward declare the operator in this case?
john
|
|
| Back to top |
|
 |
Rob Williscroft Guest
|
Posted: Thu Jun 24, 2004 10:43 pm Post subject: Re: errors = templates * friends; |
|
|
John Harrison wrote in news:2k10fiF16m7clU1 (AT) uni-berlin (DOT) de in
comp.lang.c++:
| Quote: |
Here's an example of a template friend (note all the cruft):
#include <iostream
#include
/* Forward declare X, so we can forward declare operator
*/
template < typename T > struct X;
template < typename T
std::ostream & operator << ( std::ostream &os, X< T > const & );
This confuses me, I know what to do but I still don't understand why.
Why is it necessary to forward declare the operator in this case?
|
Because the friend /statement/ in this:
template < typename T >
struct X
{
friend /* Note the <> */
std::ostream & operator << <>( std::ostream &os, X< T > const & );
};
isn't a declaration.
The following example contains a declaration but its to generic, i.e. it
grants friendship to widely, not that that is ever a /real/ problem.
#include <iostream>
#include <ostream>
template < typename T >
struct Y
{
template < typename U >
friend
std::ostream &operator << ( std::ostream &os, Y< U > const & );
};
template < typename T >
std::ostream & operator <<( std::ostream &os, Y< T > const & )
{
os << "friendn";
return os;
}
int main()
{
Y< int > y;
std::cout << y;
}
Rob.
--
http://www.victim-prime.dsl.pipex.com/
|
|
| Back to top |
|
 |
John Harrison Guest
|
Posted: Thu Jun 24, 2004 11:16 pm Post subject: Re: errors = templates * friends; |
|
|
"Rob Williscroft" <rtw (AT) freenet (DOT) co.uk> wrote
| Quote: | John Harrison wrote in news:2k10fiF16m7clU1 (AT) uni-berlin (DOT) de in
comp.lang.c++:
Here's an example of a template friend (note all the cruft):
#include <iostream
#include
/* Forward declare X, so we can forward declare operator
*/
template < typename T > struct X;
template < typename T
std::ostream & operator << ( std::ostream &os, X< T > const & );
This confuses me, I know what to do but I still don't understand why.
Why is it necessary to forward declare the operator in this case?
Because the friend /statement/ in this:
template < typename T
struct X
{
friend /* Note the <> */
std::ostream & operator << <>( std::ostream &os, X< T > const & );
};
isn't a declaration.
|
I think I'd quibble with your terminology. I guess (if I understand you
right) that I'd say although the above does declare friendship it doesn't
declare the function template itself. Which thinking about it seems
reasonable enough, it doesn't look anything like a function template
declaration.
Thanks, John
|
|
| Back to top |
|
 |
fabio de francesco Guest
|
Posted: Fri Jun 25, 2004 2:36 pm Post subject: Re: errors = templates * friends; |
|
|
Rob Williscroft <rtw (AT) freenet (DOT) co.uk> wrote
| Quote: | Here's your first problem, templates need to be defined in the
the same compilation that uses them, put these defenition's in
your header file.
// file database.cpp
...
template <typename T
DataBase
{...}
template<typename T
void DataBase
{...}
...
[snip]
....
/* Forward declare X, so we can forward declare operator
*/
template < typename T > struct X;
template < typename T
std::ostream & operator << ( std::ostream &os, X< T > const & );
template < typename T
struct X
{
friend /* Note the <> */
std::ostream & operator << <>( std::ostream &os, X< T > const & );
};
/* declaration/defenition - in the *header*
*/
template < typename T
std::ostream & operator << ( std::ostream &os, X< T > const & )
{
os << "friendn";
return os;
}
int main()
{
X< int > x;
std::cout << x;
}
|
Thank you Rob.
I actually solved the problem by using the forward declarations plus
the "<>" notation as you wrote, but fortunately I wasn't to much
inclined to put the definitions of the functions ( that are a thousand
of lines of code ) into the header file.
With this is my mind I found a way to keep untouched the code in
database.cpp by adding pre-declarations of the possible use of
template parameters ( I'm not sure I can name them this way ),
So I added ( in database.cpp ):
#include "person.h"
template DataBase<Person>;
#include "myfriends"
template DataBase<MyFriends>;
and so on. Now I can ( in usedb.cpp ) instantiate
DataBase<Person> dbPerson;
DataBase<MyFriends> dbMyFriends;
with no more linker editor errors.
Your advice was enough to make me put that friend function
implementation in database.cpp too, without any further modification.
Ciao,
Fabio De Francesco.
|
|
| Back to top |
|
 |
Wouter Lievens Guest
|
Posted: Sun Jun 27, 2004 9:24 am Post subject: Re: errors = templates * friends; |
|
|
"fabio de francesco" <fmdf (AT) tiscali (DOT) it> schreef in bericht
news:ba2f9c57.0406241018.182ef25a (AT) posting (DOT) google.com...
| Quote: | Hello,
I'm just joking with the Subject, but I really don't know how to make
a synthesis of two questions about some code I'm trying to write.
In the following I post this little code, with "..." meaning what I
think can be omitted for brevity.
// file database.h
...
template <typename T
class DataBase
{
public:
DataBase();
...
private:
...
void run();
ostream& print( ostream & );
friend ostream& operator<<(ostream &out, DataBase
{ return db.print( out ); }
};
...
// file database.cpp
...
template <typename T
DataBase
{...}
template<typename T
void DataBase
{...}
...
// file usedb.cpp
...
#include "database.h"
#include "person.h"
...
int main()
{
DataBase<Person> db; // usedb.cpp:11 (error)
...
return 0;
}
The first problem is that the linker editor ( I suppose ) comes out
with this error:
/database/src/usedb.cpp:11: undefined reference to
`DataBase<Person>::DataBase[in-charge]()'
I got the same error also if I try to instantiate 'DataBase<int> db'.
This is not the first time I use templates but I've never seen such an
error.
I'm sure I am doing some stupid thing.
The second problem arises if I try to extract the implementation code
of the friend overloaded operator "<<" from the class definition (
database.h ) to be put in the implementation file ( database.cpp ).
// file DataBase.h
...
friend ostream& operator<<( ostream &out, DataBase
...
// file DataBase.cpp
...
template<typename T
ostream& operator<<( ostream &out, DataBase
{ return db.print( out ); }
...
Here the errors, while compiling:
/src/database.h:31: warning: friend declaration `std::ostream&
operator<<(std::ostream&, DataBase
function
/src/database.h:31: warning: (if this is not what you intended, make
sure the function template has already been declared and add <> after
the function name here) -Wno-non-template-friend disables this warning
That's all. I want to thank in advance everyone who will explain what
kind of errors I put in the code. I would appreciate also any partial
reply on the first topic that is the most important for me.
Ciao,
Fabio De Francesco.
|
Templates that will be used in multiple files have to be implemented in the
header file.
That's all, I think.
|
|
| Back to top |
|
 |
fabio de francesco Guest
|
Posted: Mon Jun 28, 2004 3:48 am Post subject: Re: errors = templates * friends; |
|
|
"Wouter Lievens" <lievenswouter (AT) snotmail (DOT) com> wrote
| Quote: | Templates that will be used in multiple files have to be implemented in the
header file.
That's all, I think.
|
I think, with all respect, you'd better read all the thread, in which
more solutions have been found, before stating something that has been
outdone a few days ago (without implementing templates in the header
file).
I don't want to be polemical, it is just that someone can rely on what
is added at the end of a thread by thinking that some steps forward
have been taken after days of discussion.
Regards,
Fabio De Francesco
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|