 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Ganny Guest
|
Posted: Tue Jul 12, 2005 1:32 pm Post subject: Implicit conversions in template instantiations |
|
|
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
|
Posted: Tue Jul 12, 2005 4:21 pm Post subject: Re: Implicit conversions in template instantiations |
|
|
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
|
Posted: Thu Jul 14, 2005 8:00 am Post subject: Re: Implicit conversions in template instantiations |
|
|
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
|
Posted: Thu Jul 14, 2005 10:10 am Post subject: Re: Implicit conversions in template instantiations |
|
|
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
|
Posted: Thu Jul 14, 2005 12:15 pm Post subject: Re: Implicit conversions in template instantiations |
|
|
| 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
|
Posted: Thu Jul 14, 2005 12:18 pm Post subject: Re: Implicit conversions in template instantiations |
|
|
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
|
Posted: Thu Jul 14, 2005 5:31 pm Post subject: Re: Implicit conversions in template instantiations |
|
|
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)
{
// )
}
[ 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
|
|
| Back to top |
|
 |
Tokyo Tomy Guest
|
Posted: Fri Jul 15, 2005 11:09 am Post subject: Re: Implicit conversions in template instantiations |
|
|
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
|
Posted: Fri Jul 15, 2005 11:10 am Post subject: Re: Implicit conversions in template instantiations |
|
|
"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
|
Posted: Sun Jul 17, 2005 8:23 pm Post subject: Re: Implicit conversions in template instantiations |
|
|
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: | 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 |
|
 |
|
|
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
|
|