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 

Implicit conversions in template instantiations

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Ganny
Guest





PostPosted: Tue Jul 12, 2005 1:32 pm    Post subject: Implicit conversions in template instantiations Reply with quote



Impicit conversion exists from derived pointer to base class pointer.
However, when using this inheritance relationship when using it as type
arguments to a template, each instantiations become different types, so
no conversions exist.

#include <vector>
using namespace std;

class Base {};
class Deri : public Base {};

int main() {
Base *b1 = new Base;
Deri *d1 = new Deri;
b1 = d1; // ok
vector<Base *> *b2;
vector<Deri *> *d2;
b2 = d2; // error
}

Now, the quesion is, is there a way to provide a implicit conversion
from the C<D> to C<B> provided a conversion exists from D to B? Note
that I don't want to change the contents of C, which is not in my
control.

-Ganesh


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Thomas Richter
Guest





PostPosted: Tue Jul 12, 2005 4:21 pm    Post subject: Re: Implicit conversions in template instantiations Reply with quote



Hi,

Quote:
Impicit conversion exists from derived pointer to base class pointer.
However, when using this inheritance relationship when using it as type
arguments to a template, each instantiations become different types, so
no conversions exist.

/* snip */

Quote:
Now, the quesion is, is there a way to provide a implicit conversion
from the C<D> to C<B> provided a conversion exists from D to B?

Yes, of course. You can provide an conversion operator to convert a
C<D> to a C<B> if you want to. I don't see how this process can be
automated in general since C<D> and C<B> may act quite differently,
depending on what B and D are.

So long,
Thomas


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Tokyo Tomy
Guest





PostPosted: Thu Jul 14, 2005 8:00 am    Post subject: Re: Implicit conversions in template instantiations Reply with quote



Thomas Richter <thor (AT) mersenne (DOT) math.tu-berlin.de> wrote

Quote:
Hi,

Impicit conversion exists from derived pointer to base class pointer.
However, when using this inheritance relationship when using it as type
arguments to a template, each instantiations become different types, so
no conversions exist.

/* snip */

Now, the quesion is, is there a way to provide a implicit conversion
from the C<D> to C<B> provided a conversion exists from D to B?

Yes, of course. You can provide an conversion operator to convert a
C<D> to a C<B> if you want to.

Yes, but How? I have no idea how to provide the conversion operator.
Would you kindly give me an example code?

Quote:
I don't see how this process can be
automated in general since C<D> and C<B> may act quite differently,
depending on what B and D are.


I suppose the OP was thinking about a heterogeneous container.

[Quote from an unknown source]
There are no STL containers, which contain hetero-elements, but
objects of classes inherited from a class can be contained in STL
containers.
Template pointer parameter is only choice.
[End of quote]
You have to use some kind of down-convert.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Motti Lanzkron
Guest





PostPosted: Thu Jul 14, 2005 10:10 am    Post subject: Re: Implicit conversions in template instantiations Reply with quote

On 14 Jul 2005 04:00:11 -0400, [email]hosoda (AT) jtec (DOT) or.jp[/email] (Tokyo Tomy) wrote:

Quote:
Thomas Richter <thor (AT) mersenne (DOT) math.tu-berlin.de> wrote

Hi,

Impicit conversion exists from derived pointer to base class pointer.
However, when using this inheritance relationship when using it as type
arguments to a template, each instantiations become different types, so
no conversions exist.

/* snip */

Now, the quesion is, is there a way to provide a implicit conversion
from the C<D> to C<B> provided a conversion exists from D to B?

Yes, of course. You can provide an conversion operator to convert a
C<D> to a C<B> if you want to.

Yes, but How? I have no idea how to provide the conversion operator.
Would you kindly give me an example code?

You need a template cast operator:

template <class T>
class C {
T* p_;
public:
C(T* p = 0) : p_(p) { }

template <class U>
operator C<U>() const
{
return p_;
}
};

class Base {};
class Derived : public Base {};

int main()
{
C<Base > b;
C<Derived> d;
b = d; // ok
d = b; // error
}

Now the cast operator is valid only if T* is convertible to U*.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Ganny
Guest





PostPosted: Thu Jul 14, 2005 12:15 pm    Post subject: Re: Implicit conversions in template instantiations Reply with quote

Quote:
You need a template cast operator:
Thanks for your reply.


Quote:
Now, the quesion is, is there a way to provide a implicit conversion
from the C<D> to C<B> provided a conversion exists from D to B? Note
that I don't want to change the contents of C, which is not in my
control.
But the original problem is that I do not want to change the contents

of C.
(for example, I dont want to change std::vector for solving my specific
problem).
Is there a way to do it only by changing the definition of Base and
Derived?

-Ganesh


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Hyman Rosen
Guest





PostPosted: Thu Jul 14, 2005 12:18 pm    Post subject: Re: Implicit conversions in template instantiations Reply with quote

Motti Lanzkron wrote:
Quote:
You need a template cast operator:
template <class T> class C {...

The OP said that he needs to do it for a
template C which is not under his control.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Motti Lanzkron
Guest





PostPosted: Thu Jul 14, 2005 5:31 pm    Post subject: Re: Implicit conversions in template instantiations Reply with quote

On 14 Jul 2005 08:18:35 -0400, Hyman Rosen <hyrosen (AT) mail (DOT) com> wrote:

Quote:
Motti Lanzkron wrote:
You need a template cast operator:
template <class T> class C {...

The OP said that he needs to do it for a
template C which is not under his control.

Whoops. You're right.

I must get into the habit of actually reading posts before replying to
them.

In that case, as far as I know, there's no solution to the problem.
Maybe we could suggest an extension to the standard. Free cast
operators.

template <class From, class To>
operator C<To>(const C<From>& arg)
{
// Surprised)
}


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
leonardo77
Guest





PostPosted: Thu Jul 14, 2005 5:32 pm    Post subject: Re: Implicit conversions in template instantiations Reply with quote

http://www.parashift.com/c++-faq-lite/proper-inheritance.html#faq-21.4

The moral of the story:
You should be glad that you haven't changed vector's implementation.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Tokyo Tomy
Guest





PostPosted: Fri Jul 15, 2005 11:09 am    Post subject: Re: Implicit conversions in template instantiations Reply with quote

Motti Lanzkron <mlanzkron (AT) yahoo (DOT) co.uk> wrote

Quote:
On 14 Jul 2005 04:00:11 -0400, [email]hosoda (AT) jtec (DOT) or.jp[/email] (Tokyo Tomy) wrote:

Thomas Richter <thor (AT) mersenne (DOT) math.tu-berlin.de> wrote

Hi,

Impicit conversion exists from derived pointer to base class pointer.
However, when using this inheritance relationship when using it as type
arguments to a template, each instantiations become different types, so
no conversions exist.

[snip]


Quote:
You need a template cast operator:

template <class T
class C {
T* p_;
public:
C(T* p = 0) : p_(p) { }

template operator C {
return p_;
}
};

class Base {};
class Derived : public Base {};

int main()
{
C<Base > b;
C<Derived> d;
b = d; // ok
d = b; // error
}

Now the cast operator is valid only if T* is convertible to U*.


Beside the OP's requirement that C must not be changed, I suspect
there is an error in your code.

Your type conversion operator:
[code]
template <class U>
operator C<U>( ) const // C(T)->C(U) type conversion
{
return p_; // I don't understand here
}
[code end]

must be something below.

[code]
template <class U>
operator C<U>( ) const // C(T)->C(U) type conversion
{
C<U> c;
c.p_ = p_;
return c ;
}
[code end]

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Tokyo Tomy
Guest





PostPosted: Fri Jul 15, 2005 11:10 am    Post subject: Re: Implicit conversions in template instantiations Reply with quote

"Ganny" <sgganesh (AT) gmail (DOT) com> wrote

Quote:
Impicit conversion exists from derived pointer to base class pointer.
However, when using this inheritance relationship when using it as type
arguments to a template, each instantiations become different types, so
no conversions exist.

#include <vector
using namespace std;

class Base {};
class Deri : public Base {};

int main() {
Base *b1 = new Base;
Deri *d1 = new Deri;
b1 = d1; // ok
vector vector<Deri *> *d2;
b2 = d2; // error
}

Now, the quesion is, is there a way to provide a implicit conversion
from the C<D> to C<B> provided a conversion exists from D to B? Note
that I don't want to change the contents of C, which is not in my
control.

The posts by Motti Lanzkron inspires me to write this answerer.


If you cannot change code of vector<T>, but if you can inherit from
vector<T>, then you can write a code as below. Sorry for the dirty
code.

[code]
#include <iostream>
#include <vector>


template <class T>
class C: public std::vector<T> {
public:


template <class U>
operator C<U>( ) // C(T)->C(U) type conversion
{
C<U> c;
//std::copy(this->begin(), this->end(), c.begin());
for(typename C<T>::iterator it = this->begin(); it != this->end();
++it)
c.push_back(&(**it));

return c ;
}
};

class Base {
public:
virtual ~Base(){}; // virtual function is necessary for dynamic_cast
to do down_cast
};

class Derived : public Base {
public:
Derived(int n =0):i(n) {}
virtual ~Derived(){};
int i;
};

int main()
{

Derived element1(1);
Derived element2(2);
Derived element3(3);

C<Base* > b;
C<Derived*> d;

d.push_back(&element1);
d.push_back(&element2);
d.push_back(&element3);

b = d; // ok

for(C<Base*>::iterator it = b.begin(); it != b.end(); ++it)
std::cout << dynamic_casti << std::endl;

return 0;
}

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Motti Lanzkron
Guest





PostPosted: Sun Jul 17, 2005 8:23 pm    Post subject: Re: Implicit conversions in template instantiations Reply with quote

On 15 Jul 2005 07:09:15 -0400, [email]hosoda (AT) jtec (DOT) or.jp[/email] (Tokyo Tomy) wrote:

Quote:
Motti Lanzkron <mlanzkron (AT) yahoo (DOT) co.uk> wrote

On 14 Jul 2005 04:00:11 -0400, [email]hosoda (AT) jtec (DOT) or.jp[/email] (Tokyo Tomy) wrote:

Thomas Richter <thor (AT) mersenne (DOT) math.tu-berlin.de> wrote

Hi,

Impicit conversion exists from derived pointer to base class pointer.
However, when using this inheritance relationship when using it as type
arguments to a template, each instantiations become different types, so
no conversions exist.

[snip]

You need a template cast operator:

template <class T
class C {
T* p_;
public:
C(T* p = 0) : p_(p) { }

template operator C {
return p_;
}
};

class Base {};
class Derived : public Base {};

int main()
{
C<Base > b;
C<Derived> d;
b = d; // ok
d = b; // error
}

Now the cast operator is valid only if T* is convertible to U*.


Beside the OP's requirement that C must not be changed,

Yep, my bad.

Quote:
I suspect there is an error in your code.

I don't think so.

since C<T> has a constructor that take a single T* param it is
considered a cast operator from T* to C<T>. So p_ is cast from T* to
U* (required for the cast to work) and then from U* to C<U> (according
to the constructor).

Quote:
Your type conversion operator:
[code]
template <class U
operator CC(U) type conversion
{
return p_; // I don't understand here
// it's equivalent to:

return C<U>(static_cast<U*>(p_));
Quote:
}
[code end]


Quote:
must be something below.

[code]
template <class U
operator CC(U) type conversion
{
C<U> c;
c.p_ = p_;

This isn't legal since p_ is private to C<U> which isn't related to
C<T>.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) 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.