Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #13513 > unrolled thread
| Started by | john <gh14tq5@yahoo.com> |
|---|---|
| First post | 2012-01-20 08:56 -0500 |
| Last post | 2012-01-21 23:02 -0500 |
| Articles | 13 — 8 participants |
Back to article view | Back to comp.lang.c++
static_cast and std::vector john <gh14tq5@yahoo.com> - 2012-01-20 08:56 -0500
Re: static_cast and std::vector Leigh Johnston <leigh@i42.co.uk> - 2012-01-20 14:00 +0000
Re: static_cast and std::vector john <gh14tq5@yahoo.com> - 2012-01-20 09:58 -0500
Re: static_cast and std::vector Leigh Johnston <leigh@i42.co.uk> - 2012-01-20 15:02 +0000
Re: static_cast and std::vector john <gh14tq5@yahoo.com> - 2012-01-20 10:28 -0500
Re: static_cast and std::vector "Fred Zwarts \(KVI\)" <F.Zwarts@KVI.nl> - 2012-01-20 16:48 +0100
Re: static_cast and std::vector Leigh Johnston <leigh@i42.co.uk> - 2012-01-20 16:02 +0000
Re: static_cast and std::vector Joshua Maurice <joshuamaurice@gmail.com> - 2012-01-20 14:30 -0800
Re: static_cast and std::vector Juha Nieminen <nospam@thanks.invalid> - 2012-01-20 19:04 +0000
Re: static_cast and std::vector Tobias Müller <troplin@bluewin.ch> - 2012-01-21 08:56 +0000
Re: static_cast and std::vector john <gh14tq5@yahoo.com> - 2012-01-23 12:47 -0500
Re: static_cast and std::vector Ian Collins <ian-news@hotmail.com> - 2012-01-24 09:22 +1300
Re: static_cast and std::vector Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> - 2012-01-21 23:02 -0500
| From | john <gh14tq5@yahoo.com> |
|---|---|
| Date | 2012-01-20 08:56 -0500 |
| Subject | static_cast and std::vector |
| Message-ID | <jfbrpt$vd$1@speranza.aioe.org> |
Hi,
I am attempting to replace lots of C-style casts with static_cast's in
our code base. Most of these are simple, but there are a few that I'm
not sure what to do.
Basically, the problem is shown in the code below. GetD0/GetD1 are the
original C-style casts that work fine. I would like to change these to
C++ style casts, but the GetDD0/GetDD1 functions do not compile.
Is there a way to do this? Are there any potential problems I should be
aware of?
Thanks.
#include <vector>
class Base {};
class Derived0 : public Base {};
class Derived1 : public Base {};
class Y
{
std::vector<Base*> m_vb[2];
public:
void Add(Derived0* d0) { m_vb[0].push_back(d0); }
void Add(Derived1* d1) { m_vb[1].push_back(d1); }
const std::vector<Derived0*>* GetD0()
{ return (const std::vector<Derived0*>*) &m_vb[0]; }
const std::vector<Derived1*>* GetD1()
{ return (const std::vector<Derived1*>*) &m_vb[1]; }
const std::vector<Derived0*>* GetDD0()
{ return static_cast<const std::vector<Derived0*>*>(&m_vb[0]); }
const std::vector<Derived1*>* GetDD1()
{ return static_cast<const std::vector<Derived1*>*>(&m_vb[1]); }
};
[toc] | [next] | [standalone]
| From | Leigh Johnston <leigh@i42.co.uk> |
|---|---|
| Date | 2012-01-20 14:00 +0000 |
| Message-ID | <IIidnQOEtaTr7oTSnZ2dnUVZ8rydnZ2d@giganews.com> |
| In reply to | #13513 |
On 20/01/2012 13:56, john wrote:
> Hi,
>
> I am attempting to replace lots of C-style casts with static_cast's in
> our code base. Most of these are simple, but there are a few that I'm
> not sure what to do.
>
> Basically, the problem is shown in the code below. GetD0/GetD1 are the
> original C-style casts that work fine. I would like to change these to
> C++ style casts, but the GetDD0/GetDD1 functions do not compile.
>
> Is there a way to do this? Are there any potential problems I should be
> aware of?
>
> Thanks.
>
> #include <vector>
>
> class Base {};
> class Derived0 : public Base {};
> class Derived1 : public Base {};
>
> class Y
> {
> std::vector<Base*> m_vb[2];
>
> public:
>
> void Add(Derived0* d0) { m_vb[0].push_back(d0); }
> void Add(Derived1* d1) { m_vb[1].push_back(d1); }
>
> const std::vector<Derived0*>* GetD0()
> { return (const std::vector<Derived0*>*) &m_vb[0]; }
> const std::vector<Derived1*>* GetD1()
> { return (const std::vector<Derived1*>*) &m_vb[1]; }
>
> const std::vector<Derived0*>* GetDD0()
> { return static_cast<const std::vector<Derived0*>*>(&m_vb[0]); }
> const std::vector<Derived1*>* GetDD1()
> { return static_cast<const std::vector<Derived1*>*>(&m_vb[1]); }
>
> };
Both the C-style cast and the static_cast are wrong; you cannot cast a
std::vector<base*> to a std::vector<derived*>.
Instead have these getter functions return a std::vector<base*> and
downcast (using static_cast or dynamic_cast) the vector's elements
instead elsewhere in your code.
/Leigh
[toc] | [prev] | [next] | [standalone]
| From | john <gh14tq5@yahoo.com> |
|---|---|
| Date | 2012-01-20 09:58 -0500 |
| Message-ID | <jfbveg$ae0$1@speranza.aioe.org> |
| In reply to | #13514 |
On 1/20/2012 9:00 AM, Leigh Johnston wrote:
> On 20/01/2012 13:56, john wrote:
>> Hi,
>>
>> I am attempting to replace lots of C-style casts with static_cast's in
>> our code base. Most of these are simple, but there are a few that I'm
>> not sure what to do.
>>
>> Basically, the problem is shown in the code below. GetD0/GetD1 are the
>> original C-style casts that work fine. I would like to change these to
>> C++ style casts, but the GetDD0/GetDD1 functions do not compile.
>>
>> Is there a way to do this? Are there any potential problems I should be
>> aware of?
>>
>> Thanks.
>>
>> #include <vector>
>>
>> class Base {};
>> class Derived0 : public Base {};
>> class Derived1 : public Base {};
>>
>> class Y
>> {
>> std::vector<Base*> m_vb[2];
>>
>> public:
>>
>> void Add(Derived0* d0) { m_vb[0].push_back(d0); }
>> void Add(Derived1* d1) { m_vb[1].push_back(d1); }
>>
>> const std::vector<Derived0*>* GetD0()
>> { return (const std::vector<Derived0*>*) &m_vb[0]; }
>> const std::vector<Derived1*>* GetD1()
>> { return (const std::vector<Derived1*>*) &m_vb[1]; }
>>
>> const std::vector<Derived0*>* GetDD0()
>> { return static_cast<const std::vector<Derived0*>*>(&m_vb[0]); }
>> const std::vector<Derived1*>* GetDD1()
>> { return static_cast<const std::vector<Derived1*>*>(&m_vb[1]); }
>>
>> };
>
> Both the C-style cast and the static_cast are wrong; you cannot cast a
> std::vector<base*> to a std::vector<derived*>.
>
> Instead have these getter functions return a std::vector<base*> and
> downcast (using static_cast or dynamic_cast) the vector's elements
> instead elsewhere in your code.
>
> /Leigh
I do not see why the C-style cast is wrong. It works flawlessly across
a wide range of compilers and systems. I can understand the problem
with C++ static_cast, but I was hoping there was a way around it. If
there is not a valid C++ way to do this, I'll leave it as is.
[toc] | [prev] | [next] | [standalone]
| From | Leigh Johnston <leigh@i42.co.uk> |
|---|---|
| Date | 2012-01-20 15:02 +0000 |
| Message-ID | <A4mdnUVc_IZqHITSnZ2dnUVZ8tqdnZ2d@giganews.com> |
| In reply to | #13518 |
On 20/01/2012 14:58, john wrote:
> On 1/20/2012 9:00 AM, Leigh Johnston wrote:
>> On 20/01/2012 13:56, john wrote:
>>> Hi,
>>>
>>> I am attempting to replace lots of C-style casts with static_cast's in
>>> our code base. Most of these are simple, but there are a few that I'm
>>> not sure what to do.
>>>
>>> Basically, the problem is shown in the code below. GetD0/GetD1 are the
>>> original C-style casts that work fine. I would like to change these to
>>> C++ style casts, but the GetDD0/GetDD1 functions do not compile.
>>>
>>> Is there a way to do this? Are there any potential problems I should be
>>> aware of?
>>>
>>> Thanks.
>>>
>>> #include <vector>
>>>
>>> class Base {};
>>> class Derived0 : public Base {};
>>> class Derived1 : public Base {};
>>>
>>> class Y
>>> {
>>> std::vector<Base*> m_vb[2];
>>>
>>> public:
>>>
>>> void Add(Derived0* d0) { m_vb[0].push_back(d0); }
>>> void Add(Derived1* d1) { m_vb[1].push_back(d1); }
>>>
>>> const std::vector<Derived0*>* GetD0()
>>> { return (const std::vector<Derived0*>*) &m_vb[0]; }
>>> const std::vector<Derived1*>* GetD1()
>>> { return (const std::vector<Derived1*>*) &m_vb[1]; }
>>>
>>> const std::vector<Derived0*>* GetDD0()
>>> { return static_cast<const std::vector<Derived0*>*>(&m_vb[0]); }
>>> const std::vector<Derived1*>* GetDD1()
>>> { return static_cast<const std::vector<Derived1*>*>(&m_vb[1]); }
>>>
>>> };
>>
>> Both the C-style cast and the static_cast are wrong; you cannot cast a
>> std::vector<base*> to a std::vector<derived*>.
>>
>> Instead have these getter functions return a std::vector<base*> and
>> downcast (using static_cast or dynamic_cast) the vector's elements
>> instead elsewhere in your code.
>>
>> /Leigh
>
>
> I do not see why the C-style cast is wrong. It works flawlessly across a
> wide range of compilers and systems. I can understand the problem with
> C++ static_cast, but I was hoping there was a way around it. If there is
> not a valid C++ way to do this, I'll leave it as is.
Just because something "works" does not means that it is "correct". The
language allows you to perform the C style cast (or reinterpret_cast)
however *using* the resultant object reference by invoking a std::vector
member function results in undefined behaviour. Undefined behaviour can
"silently work" on a particular implementation but that does not mean it
is correct; it isn't, it is a bug. The basic reason why this is the
case here is due to the fact that std::vector<base*> and
std::vector<derived*> are unrelated types.
/Leigh
[toc] | [prev] | [next] | [standalone]
| From | john <gh14tq5@yahoo.com> |
|---|---|
| Date | 2012-01-20 10:28 -0500 |
| Message-ID | <jfc17g$euc$1@speranza.aioe.org> |
| In reply to | #13519 |
>>> >>> Both the C-style cast and the static_cast are wrong; you cannot cast a >>> std::vector<base*> to a std::vector<derived*>. >>> >>> Instead have these getter functions return a std::vector<base*> and >>> downcast (using static_cast or dynamic_cast) the vector's elements >>> instead elsewhere in your code. >>> >>> /Leigh >> >> >> I do not see why the C-style cast is wrong. It works flawlessly across a >> wide range of compilers and systems. I can understand the problem with >> C++ static_cast, but I was hoping there was a way around it. If there is >> not a valid C++ way to do this, I'll leave it as is. > > Just because something "works" does not means that it is "correct". The > language allows you to perform the C style cast (or reinterpret_cast) > however *using* the resultant object reference by invoking a std::vector > member function results in undefined behaviour. Undefined behaviour can > "silently work" on a particular implementation but that does not mean it > is correct; it isn't, it is a bug. The basic reason why this is the case > here is due to the fact that std::vector<base*> and > std::vector<derived*> are unrelated types. > Ok. Thanks for the explanation. I may look into fixing this according to your suggestion. John
[toc] | [prev] | [next] | [standalone]
| From | "Fred Zwarts \(KVI\)" <F.Zwarts@KVI.nl> |
|---|---|
| Date | 2012-01-20 16:48 +0100 |
| Message-ID | <jfc2dc$4b3$1@news.albasani.net> |
| In reply to | #13518 |
"john" wrote in message news:jfbveg$ae0$1@speranza.aioe.org...
>
>On 1/20/2012 9:00 AM, Leigh Johnston wrote:
>> On 20/01/2012 13:56, john wrote:
>>> Hi,
>>>
>>> I am attempting to replace lots of C-style casts with static_cast's in
>>> our code base. Most of these are simple, but there are a few that I'm
>>> not sure what to do.
>>>
>>> Basically, the problem is shown in the code below. GetD0/GetD1 are the
>>> original C-style casts that work fine. I would like to change these to
>>> C++ style casts, but the GetDD0/GetDD1 functions do not compile.
>>>
>>> Is there a way to do this? Are there any potential problems I should be
>>> aware of?
>>>
>>> Thanks.
>>>
>>> #include <vector>
>>>
>>> class Base {};
>>> class Derived0 : public Base {};
>>> class Derived1 : public Base {};
>>>
>>> class Y
>>> {
>>> std::vector<Base*> m_vb[2];
>>>
>>> public:
>>>
>>> void Add(Derived0* d0) { m_vb[0].push_back(d0); }
>>> void Add(Derived1* d1) { m_vb[1].push_back(d1); }
>>>
>>> const std::vector<Derived0*>* GetD0()
>>> { return (const std::vector<Derived0*>*) &m_vb[0]; }
>>> const std::vector<Derived1*>* GetD1()
>>> { return (const std::vector<Derived1*>*) &m_vb[1]; }
>>>
>>> const std::vector<Derived0*>* GetDD0()
>>> { return static_cast<const std::vector<Derived0*>*>(&m_vb[0]); }
>>> const std::vector<Derived1*>* GetDD1()
>>> { return static_cast<const std::vector<Derived1*>*>(&m_vb[1]); }
>>>
>>> };
>>
>> Both the C-style cast and the static_cast are wrong; you cannot cast a
>> std::vector<base*> to a std::vector<derived*>.
>>
>> Instead have these getter functions return a std::vector<base*> and
>> downcast (using static_cast or dynamic_cast) the vector's elements
>> instead elsewhere in your code.
>>
>> /Leigh
>
>
>I do not see why the C-style cast is wrong. It works flawlessly across a
>wide range of compilers and systems.
It may work in the case of simple inheritance, but it usually fails when
multiple and/or virtual inheritance is going to be used.
[toc] | [prev] | [next] | [standalone]
| From | Leigh Johnston <leigh@i42.co.uk> |
|---|---|
| Date | 2012-01-20 16:02 +0000 |
| Message-ID | <c9ednRt0F8u1DYTSnZ2dnUVZ8oOdnZ2d@giganews.com> |
| In reply to | #13521 |
On 20/01/2012 15:48, Fred Zwarts (KVI) wrote:
> "john" wrote in message news:jfbveg$ae0$1@speranza.aioe.org...
>>
>> On 1/20/2012 9:00 AM, Leigh Johnston wrote:
>>> On 20/01/2012 13:56, john wrote:
>>>> Hi,
>>>>
>>>> I am attempting to replace lots of C-style casts with static_cast's in
>>>> our code base. Most of these are simple, but there are a few that I'm
>>>> not sure what to do.
>>>>
>>>> Basically, the problem is shown in the code below. GetD0/GetD1 are the
>>>> original C-style casts that work fine. I would like to change these to
>>>> C++ style casts, but the GetDD0/GetDD1 functions do not compile.
>>>>
>>>> Is there a way to do this? Are there any potential problems I should be
>>>> aware of?
>>>>
>>>> Thanks.
>>>>
>>>> #include <vector>
>>>>
>>>> class Base {};
>>>> class Derived0 : public Base {};
>>>> class Derived1 : public Base {};
>>>>
>>>> class Y
>>>> {
>>>> std::vector<Base*> m_vb[2];
>>>>
>>>> public:
>>>>
>>>> void Add(Derived0* d0) { m_vb[0].push_back(d0); }
>>>> void Add(Derived1* d1) { m_vb[1].push_back(d1); }
>>>>
>>>> const std::vector<Derived0*>* GetD0()
>>>> { return (const std::vector<Derived0*>*) &m_vb[0]; }
>>>> const std::vector<Derived1*>* GetD1()
>>>> { return (const std::vector<Derived1*>*) &m_vb[1]; }
>>>>
>>>> const std::vector<Derived0*>* GetDD0()
>>>> { return static_cast<const std::vector<Derived0*>*>(&m_vb[0]); }
>>>> const std::vector<Derived1*>* GetDD1()
>>>> { return static_cast<const std::vector<Derived1*>*>(&m_vb[1]); }
>>>>
>>>> };
>>>
>>> Both the C-style cast and the static_cast are wrong; you cannot cast a
>>> std::vector<base*> to a std::vector<derived*>.
>>>
>>> Instead have these getter functions return a std::vector<base*> and
>>> downcast (using static_cast or dynamic_cast) the vector's elements
>>> instead elsewhere in your code.
>>>
>>> /Leigh
>>
>>
>> I do not see why the C-style cast is wrong. It works flawlessly across
>> a wide range of compilers and systems.
>
> It may work in the case of simple inheritance, but it usually fails when
> multiple and/or virtual inheritance is going to be used.
This is not "simple inheritance" as the types involved are unrelated.
/Leigh
[toc] | [prev] | [next] | [standalone]
| From | Joshua Maurice <joshuamaurice@gmail.com> |
|---|---|
| Date | 2012-01-20 14:30 -0800 |
| Message-ID | <07acf11c-97a6-4d78-ad7b-1f893af19c49@y5g2000pbk.googlegroups.com> |
| In reply to | #13522 |
On Jan 20, 8:02 am, Leigh Johnston <le...@i42.co.uk> wrote: > On 20/01/2012 15:48, Fred Zwarts (KVI) wrote: > > > "john" wrote in messagenews:jfbveg$ae0$1@speranza.aioe.org... > > >> On 1/20/2012 9:00 AM, Leigh Johnston wrote: > >>> On 20/01/2012 13:56, john wrote: > >>> Both the C-style cast and the static_cast are wrong; you cannot cast a > >>> std::vector<base*> to a std::vector<derived*>. > > >> I do not see why the C-style cast is wrong. It works flawlessly across > >> a wide range of compilers and systems. > > > It may work in the case of simple inheritance, but it usually fails when > > multiple and/or virtual inheritance is going to be used. > > This is not "simple inheritance" as the types involved are unrelated. Fred Zwarts meant to say that if the contained types have a simple inheritance relationship, then as a matter of coincidence and facts of implementations, it's likely to work (even UB programs can work in some cases), but if the contained types are multiple or virtual inheritance, then it starts becoming much less likely. He did not mean to imply the vectors are related by inheritance, nor that the casting of the OP is not UB, nor that writing UB code is sound advice.
[toc] | [prev] | [next] | [standalone]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2012-01-20 19:04 +0000 |
| Message-ID | <4f19bab4$0$4387$7b1e8fa0@news.nbl.fi> |
| In reply to | #13518 |
john <gh14tq5@yahoo.com> wrote: > I do not see why the C-style cast is wrong. Because it's bypassing the language's type checking mechanism, and in this case doing so in a manner that's potentially hazardous. std::vector<A*> and std::vector<B*> are two completely different and independent classes that have no relation to each other (just because they are created from the same *template* doesn't make them related; the template is used by the compiler to create two different classes). In principle it would be possible for the two classes to even have completely different implementations (via template specialization). More importantly, though, it's theoretically possible for sizeof(A*) and sizeof(B*) to be different, which would immediately break any code that assumed to have a std::vector<A*> but is in reality given a std::vector<B*>. That's the reason why static_cast won't allow you to do that: It's a safer type checking mechanism than the C style cast (which is basically a reinterpret_cast). > It works flawlessly across > a wide range of compilers and systems. If you make this code only for yourself and know how the underlying system works, then you could bypass the type checking meachanism as you did, as long as you understand why it's wrong in principle.
[toc] | [prev] | [next] | [standalone]
| From | Tobias Müller <troplin@bluewin.ch> |
|---|---|
| Date | 2012-01-21 08:56 +0000 |
| Message-ID | <953898973348828453.949041troplin-bluewin.ch@news.aioe.org> |
| In reply to | #13513 |
john <gh14tq5@yahoo.com> wrote:
> Hi,
>
> I am attempting to replace lots of C-style casts with static_cast's in
> our code base. Most of these are simple, but there are a few that I'm not sure what to do.
>
> Basically, the problem is shown in the code below. GetD0/GetD1 are the
> original C-style casts that work fine. I would like to change these to
> C++ style casts, but the GetDD0/GetDD1 functions do not compile.
>
> Is there a way to do this? Are there any potential problems I should be aware of?
>
> Thanks.
>
> #include <vector>
>
> class Base {};
> class Derived0 : public Base {};
> class Derived1 : public Base {};
>
> class Y
> {
> std::vector<Base*> m_vb[2];
>
> public:
>
> void Add(Derived0* d0) { m_vb[0].push_back(d0); }
> void Add(Derived1* d1) { m_vb[1].push_back(d1); }
>
> const std::vector<Derived0*>* GetD0()
> { return (const std::vector<Derived0*>*) &m_vb[0]; }
> const std::vector<Derived1*>* GetD1()
> { return (const std::vector<Derived1*>*) &m_vb[1]; }
>
> const std::vector<Derived0*>* GetDD0()
> { return static_cast<const std::vector<Derived0*>*>(&m_vb[0]); }
> const std::vector<Derived1*>* GetDD1()
> { return static_cast<const std::vector<Derived1*>*>(&m_vb[1]); }
>
> };
Why don't you just write:
std::vector<Derived0*> m_vd0;
std::vector<Derived1*> m_vd1;
and use those without any casting?
This would be the most obvious solution and you are losing nothing.
Tobi
[toc] | [prev] | [next] | [standalone]
| From | john <gh14tq5@yahoo.com> |
|---|---|
| Date | 2012-01-23 12:47 -0500 |
| Message-ID | <jfk6fm$du4$1@speranza.aioe.org> |
| In reply to | #13530 |
>> #include<vector>
>>
>> class Base {};
>> class Derived0 : public Base {};
>> class Derived1 : public Base {};
>>
>> class Y
>> {
>> std::vector<Base*> m_vb[2];
>>
>> public:
>>
>> void Add(Derived0* d0) { m_vb[0].push_back(d0); }
>> void Add(Derived1* d1) { m_vb[1].push_back(d1); }
>>
>> const std::vector<Derived0*>* GetD0()
>> { return (const std::vector<Derived0*>*)&m_vb[0]; }
>> const std::vector<Derived1*>* GetD1()
>> { return (const std::vector<Derived1*>*)&m_vb[1]; }
>>
>> const std::vector<Derived0*>* GetDD0()
>> { return static_cast<const std::vector<Derived0*>*>(&m_vb[0]); }
>> const std::vector<Derived1*>* GetDD1()
>> { return static_cast<const std::vector<Derived1*>*>(&m_vb[1]); }
>>
>> };
>
> Why don't you just write:
> std::vector<Derived0*> m_vd0;
> std::vector<Derived1*> m_vd1;
> and use those without any casting?
>
> This would be the most obvious solution and you are losing nothing.
We have looked into this, but we also really need functionality like
const std::vector<Base*>* GetBase(int which)
{ return &m_vb[which]; }
So, changing as you suggested would preclude this. Would it be possible
to replace the UB casts
const std::vector<Derived0*>* GetD0()
{ return (const std::vector<Derived0*>*)&m_vb[0]; }
const std::vector<Derived1*>* GetD1()
{ return (const std::vector<Derived1*>*)&m_vb[1]; }
with some type of specialized iterator?
Thanks.
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-01-24 09:22 +1300 |
| Message-ID | <9o5tsuFbb0U1@mid.individual.net> |
| In reply to | #13555 |
On 01/24/12 06:47 AM, john wrote:
>>> #include<vector>
>>>
>>> class Base {};
>>> class Derived0 : public Base {};
>>> class Derived1 : public Base {};
>>>
>>> class Y
>>> {
>>> std::vector<Base*> m_vb[2];
>>>
>>> public:
>>>
>>> void Add(Derived0* d0) { m_vb[0].push_back(d0); }
>>> void Add(Derived1* d1) { m_vb[1].push_back(d1); }
>>>
>>> const std::vector<Derived0*>* GetD0()
>>> { return (const std::vector<Derived0*>*)&m_vb[0]; }
>>> const std::vector<Derived1*>* GetD1()
>>> { return (const std::vector<Derived1*>*)&m_vb[1]; }
>>>
>>> const std::vector<Derived0*>* GetDD0()
>>> { return static_cast<const std::vector<Derived0*>*>(&m_vb[0]); }
>>> const std::vector<Derived1*>* GetDD1()
>>> { return static_cast<const std::vector<Derived1*>*>(&m_vb[1]); }
>>>
>>> };
>>
>> Why don't you just write:
>> std::vector<Derived0*> m_vd0;
>> std::vector<Derived1*> m_vd1;
>> and use those without any casting?
>>
>> This would be the most obvious solution and you are losing nothing.
>
> We have looked into this, but we also really need functionality like
>
> const std::vector<Base*>* GetBase(int which)
> { return&m_vb[which]; }
>
> So, changing as you suggested would preclude this. Would it be possible
> to replace the UB casts
>
> const std::vector<Derived0*>* GetD0()
> { return (const std::vector<Derived0*>*)&m_vb[0]; }
> const std::vector<Derived1*>* GetD1()
> { return (const std::vector<Derived1*>*)&m_vb[1]; }
>
> with some type of specialized iterator?
What do you do with the returned vectors?
You don't have a vector of Derived0* to return, which is why others have
told you the casts are UB. If you are iterating through them, you could
add a (template) method to perform the iteration with the appropriate
cast of the vector elements (not the vector) to your container class.
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> |
|---|---|
| Date | 2012-01-21 23:02 -0500 |
| Message-ID | <4f1b8a5e$0$9594$c3e8da3$9b4ff22a@news.astraweb.com> |
| In reply to | #13513 |
john wrote:
> Hi,
>
> I am attempting to replace lots of C-style casts with static_cast's in our code
> base. Most of these are simple, but there are a few that I'm not sure what to do.
>
> Basically, the problem is shown in the code below. GetD0/GetD1 are the original
> C-style casts that work fine. I would like to change these to C++ style casts,
> but the GetDD0/GetDD1 functions do not compile.
>
> Is there a way to do this? Are there any potential problems I should be aware of?
>
> Thanks.
>
> #include <vector>
>
> class Base {};
> class Derived0 : public Base {};
> class Derived1 : public Base {};
>
> class Y
> {
> std::vector<Base*> m_vb[2];
>
> public:
>
> void Add(Derived0* d0) { m_vb[0].push_back(d0); }
> void Add(Derived1* d1) { m_vb[1].push_back(d1); }
>
> const std::vector<Derived0*>* GetD0()
> { return (const std::vector<Derived0*>*) &m_vb[0]; }
> const std::vector<Derived1*>* GetD1()
> { return (const std::vector<Derived1*>*) &m_vb[1]; }
>
> const std::vector<Derived0*>* GetDD0()
> { return static_cast<const std::vector<Derived0*>*>(&m_vb[0]); }
> const std::vector<Derived1*>* GetDD1()
> { return static_cast<const std::vector<Derived1*>*>(&m_vb[1]); }
>
> };
>
Technically, C-style cast in this case is reinterpret_cast<>, not static_cast<>
so you have to be able to compile after converting to reinterpret_cast<>.
(I know the resulting code will stay UB and that two UBs are theoretically never
equal; but from practical perspective I would bet old and new UBs will not be
too different; and quite possible, new code will continue "work fine" in the
same situations as the old code did).
-Pavel
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web