Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Re: operator<< template declaration problem (http://www.velocityreviews.com/forums/t267643-re-operator-template-declaration-problem.html)

porschberg 06-24-2003 05:25 AM

Re: operator<< template declaration problem
 
Of course this works, but then I have to update my template header
file every time I instantiate a new template.
This is not very smart. Is there no better way ?

Chandra Shekhar Kumar <chandra.kumar@oracle.com> wrote in message news:<3EF667AD.80B2ABA@oracle.com>...
> keep the implementation in the header file for all the templates
>
> porschberg wrote:
>
> > Hello,
> > I try to find a template implementation for a set of classes and thereby
> > I encounter problems with the operator<<.
> > The origin class layout looks as follows:
> >
> > P_WHReasonUpdate.hh
> > ===================
> > //a class to perform a update on table P_WHReason
> > class P_WHReasonUpdate
> > {
> > public:
> > ...
> > ...
> > class row{
> > ...
> > }
> >
> > typedef shared_ptr<P_WHReasonUpdate::row> ROW;
> > typedef vector<ROW>::iterator iter;
> > typedef pair<iter, iter>iterPair;
> > privat:
> > otl_connect& db;
> > otl_nocommit_stream i;
> > size_t array_size;
> > vector<ROW> v;
> > ...
> > };
> >
> > otl_stream& operator<<(otl_stream& s, const P_WHReasonUpdate::row& row);
> >
> > P_WHReasonUpdate.cc
> > ===================
> >
> > otl_stream& operator<<(otl_stream& s, const P_WHReasonUpdate::ROW & row)
> > {
> > ... impl ...
> > return s;
> > }
> >
> > void P_WHReasonUpdate::flush()
> > {
> > ...
> > i << (*myIterator); // i is of type otl_stream
> > ...
> > }
> >
> > All this works fine....
> > -------------------------------
> >
> > Now my template attempt (Update.hh):
> >
> > template <class T>
> > class Update
> > {
> > public:
> >
> > typedef shared_ptr<typename T::row> ROW;
> > typedef typename vector<ROW>::iterator iter;
> > friend otl_stream& operator<< <> (otl_stream &output, const typename T::row& row);
> > ...
> > ...
> > };
> >
> > //Use of the template in a test.cc
> > Update<P_WHReasonUpdate> myUpdate(db);
> >
> > In Update.hh I still have my flush() method which does
> >
> > i << (*myIterator); // i is of type otl_stream
> >
> > The implementation of the overloaded operator<< is
> > still in P_WHReasonUpdate.cc and therefore without the friend line
> > I get from the compiler:
> > Update.hh:109: error: no match for `otl_tmpl_nocommit_stream<otl_stream, ...
> >
> > With the friend line I get:
> > Update.hh:39: error: template-id `operator<< <>' for `otl_stream&
> > operator<<(otl_stream&, const P_WHReasonUpdate::row&)' does not match any
> > template declaration
> >
> > I think I need a forward declaration of the operator-overloading in my
> > template class Update.hh and at link time the implementation from
> > P_WHReasonUpdate.cc will used.
> >
> > My question: What is the way to achieve this ?
> >
> > Thanks for every help !
> > Thomas


tom_usenet 06-24-2003 10:56 AM

Re: operator<< template declaration problem
 
On 23 Jun 2003 22:25:14 -0700, thomas.porschberg@osp-dd.de
(porschberg) wrote:

>Of course this works, but then I have to update my template header
>file every time I instantiate a new template.
>This is not very smart. Is there no better way ?


No, implicit instantation automatically creates the required
instantiations - this is why putting template definitions in the
header is the norm, since it requires no special maintenance. It does
however mean that code that uses the template is dependent on its
implementation.

But there is another way. Read down.

>> > Now my template attempt (Update.hh):
>> >
>> > template <class T>
>> > class Update
>> > {
>> > public:
>> >
>> > typedef shared_ptr<typename T::row> ROW;
>> > typedef typename vector<ROW>::iterator iter;
>> > friend otl_stream& operator<< <> (otl_stream &output, const typename T::row& row);


Make the above a non-template. You aren't going to be able to deduce T
in a call anyway. Consider this:

struct Foo
{
typedef int row;
};

struct Bar
{
typedef int row;
};

otl_stream << 5; //calls operator<< <Foo> or <Bar>!?

You can't deduce template arguments from nested types. So change your
friend declaration to:

//non-template friend:
friend otl_stream& operator<<(otl_stream &output, const typename
T::row& row);



>> > ...
>> > ...
>> > };
>> >


In update.cc:

otl_stream& operator<<(otl_stream &output, const int& row)
{
//definition
}

otl_stream& operator<<(otl_stream &output, const whatever& row)
{
//definition
}

etc. Obviously, you could use another template in the .cc file and
forward the definitions to that to save duplication.


>> > //Use of the template in a test.cc
>> > Update<P_WHReasonUpdate> myUpdate(db);
>> >
>> > In Update.hh I still have my flush() method which does
>> >
>> > i << (*myIterator); // i is of type otl_stream
>> >
>> > The implementation of the overloaded operator<< is
>> > still in P_WHReasonUpdate.cc and therefore without the friend line
>> > I get from the compiler:
>> > Update.hh:109: error: no match for `otl_tmpl_nocommit_stream<otl_stream, ...
>> >
>> > With the friend line I get:
>> > Update.hh:39: error: template-id `operator<< <>' for `otl_stream&
>> > operator<<(otl_stream&, const P_WHReasonUpdate::row&)' does not match any
>> > template declaration
>> >
>> > I think I need a forward declaration of the operator-overloading in my
>> > template class Update.hh and at link time the implementation from
>> > P_WHReasonUpdate.cc will used.
>> >
>> > My question: What is the way to achieve this ?


Not with the template as is, since template argument deduction cannot
work on the template as you have currently written it. However, in the
normal case you do this:

In .h:

template class forward declaration

template function (needing friendship) forward declaration

template class definition, including friend (as you wrote it)

In .cpp

Explicit instantion of required versions.

Tom

porschberg 06-24-2003 01:19 PM

Re: operator<< template declaration problem
 
Thanks a lot for your advice.
I still get a compiler warning

Update.hh:63: warning: friend declaration `otl_stream& operator<<(otl_stream&,
const boost::shared_ptr<typename T::row>&)' declares a non-template function
Update.hh:63: 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

but there is nothing wrong with operator<< because it is not a
template function. Right?!
My real implementation is in *.cc.

tom_usenet@hotmail.com (tom_usenet) wrote in message news:<3ef82b52.89736515@news.easynet.co.uk>...
> On 23 Jun 2003 22:25:14 -0700, thomas.porschberg@osp-dd.de
> (porschberg) wrote:
>
> >Of course this works, but then I have to update my template header
> >file every time I instantiate a new template.
> >This is not very smart. Is there no better way ?

>
> No, implicit instantation automatically creates the required
> instantiations - this is why putting template definitions in the
> header is the norm, since it requires no special maintenance. It does
> however mean that code that uses the template is dependent on its
> implementation.
>
> But there is another way. Read down.
>
> >> > Now my template attempt (Update.hh):
> >> >
> >> > template <class T>
> >> > class Update
> >> > {
> >> > public:
> >> >
> >> > typedef shared_ptr<typename T::row> ROW;
> >> > typedef typename vector<ROW>::iterator iter;
> >> > friend otl_stream& operator<< <> (otl_stream &output, const typename T::row& row);

>
> Make the above a non-template. You aren't going to be able to deduce T
> in a call anyway. Consider this:
>
> struct Foo
> {
> typedef int row;
> };
>
> struct Bar
> {
> typedef int row;
> };
>
> otl_stream << 5; //calls operator<< <Foo> or <Bar>!?
>
> You can't deduce template arguments from nested types. So change your
> friend declaration to:
>
> //non-template friend:
> friend otl_stream& operator<<(otl_stream &output, const typename
> T::row& row);
>
>
>
> >> > ...
> >> > ...
> >> > };
> >> >

>
> In update.cc:
>
> otl_stream& operator<<(otl_stream &output, const int& row)
> {
> //definition
> }
>
> otl_stream& operator<<(otl_stream &output, const whatever& row)
> {
> //definition
> }
>
> etc. Obviously, you could use another template in the .cc file and
> forward the definitions to that to save duplication.
>
>
> >> > //Use of the template in a test.cc
> >> > Update<P_WHReasonUpdate> myUpdate(db);
> >> >
> >> > In Update.hh I still have my flush() method which does
> >> >
> >> > i << (*myIterator); // i is of type otl_stream
> >> >
> >> > The implementation of the overloaded operator<< is
> >> > still in P_WHReasonUpdate.cc and therefore without the friend line
> >> > I get from the compiler:
> >> > Update.hh:109: error: no match for `otl_tmpl_nocommit_stream<otl_stream, ...
> >> >
> >> > With the friend line I get:
> >> > Update.hh:39: error: template-id `operator<< <>' for `otl_stream&
> >> > operator<<(otl_stream&, const P_WHReasonUpdate::row&)' does not match any
> >> > template declaration
> >> >
> >> > I think I need a forward declaration of the operator-overloading in my
> >> > template class Update.hh and at link time the implementation from
> >> > P_WHReasonUpdate.cc will used.
> >> >
> >> > My question: What is the way to achieve this ?

>
> Not with the template as is, since template argument deduction cannot
> work on the template as you have currently written it. However, in the
> normal case you do this:
>
> In .h:
>
> template class forward declaration
>
> template function (needing friendship) forward declaration
>
> template class definition, including friend (as you wrote it)
>
> In .cpp
>
> Explicit instantion of required versions.
>
> Tom


tom_usenet 06-24-2003 01:48 PM

Re: operator<< template declaration problem
 
On 24 Jun 2003 06:19:31 -0700, thomas.porschberg@osp-dd.de
(porschberg) wrote:

>Thanks a lot for your advice.
>I still get a compiler warning
>
>Update.hh:63: warning: friend declaration `otl_stream& operator<<(otl_stream&,
> const boost::shared_ptr<typename T::row>&)' declares a non-template function
>Update.hh:63: 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
>
>but there is nothing wrong with operator<< because it is not a
>template function. Right?!


Right. Normally it is a mistake (you intended a template function),
but in your case it isn't. That looks like a gcc warning. See here:

http://gcc.gnu.org/faq.html#friend

Tom


All times are GMT. The time now is 10:50 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.