C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

errors = templates * friends;

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
fabio de francesco
Guest





PostPosted: Thu Jun 24, 2004 6:18 pm    Post subject: errors = templates * friends; Reply with 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<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





PostPosted: Thu Jun 24, 2004 6:42 pm    Post subject: Re: errors = templates * friends; Reply with quote



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 Smile.

Rob.
--
http://www.victim-prime.dsl.pipex.com/

Back to top
John Harrison
Guest





PostPosted: Thu Jun 24, 2004 9:47 pm    Post subject: Re: errors = templates * friends; Reply with quote



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





PostPosted: Thu Jun 24, 2004 10:43 pm    Post subject: Re: errors = templates * friends; Reply with quote

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





PostPosted: Thu Jun 24, 2004 11:16 pm    Post subject: Re: errors = templates * friends; Reply with quote


"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





PostPosted: Fri Jun 25, 2004 2:36 pm    Post subject: Re: errors = templates * friends; Reply with quote

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





PostPosted: Sun Jun 27, 2004 9:24 am    Post subject: Re: errors = templates * friends; Reply with quote

"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





PostPosted: Mon Jun 28, 2004 3:48 am    Post subject: Re: errors = templates * friends; Reply with quote

"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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.