Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #13513 > unrolled thread

static_cast and std::vector

Started byjohn <gh14tq5@yahoo.com>
First post2012-01-20 08:56 -0500
Last post2012-01-21 23:02 -0500
Articles 13 — 8 participants

Back to article view | Back to comp.lang.c++


Contents

  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

#13513 — static_cast and std::vector

Fromjohn <gh14tq5@yahoo.com>
Date2012-01-20 08:56 -0500
Subjectstatic_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]


#13514

FromLeigh Johnston <leigh@i42.co.uk>
Date2012-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]


#13518

Fromjohn <gh14tq5@yahoo.com>
Date2012-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]


#13519

FromLeigh Johnston <leigh@i42.co.uk>
Date2012-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]


#13520

Fromjohn <gh14tq5@yahoo.com>
Date2012-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]


#13521

From"Fred Zwarts \(KVI\)" <F.Zwarts@KVI.nl>
Date2012-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]


#13522

FromLeigh Johnston <leigh@i42.co.uk>
Date2012-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]


#13525

FromJoshua Maurice <joshuamaurice@gmail.com>
Date2012-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]


#13524

FromJuha Nieminen <nospam@thanks.invalid>
Date2012-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]


#13530

FromTobias Müller <troplin@bluewin.ch>
Date2012-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]


#13555

Fromjohn <gh14tq5@yahoo.com>
Date2012-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]


#13556

FromIan Collins <ian-news@hotmail.com>
Date2012-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]


#13538

FromPavel <pauldontspamtolk@removeyourself.dontspam.yahoo>
Date2012-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