473,396 Members | 1,913 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

vector <Base *> = vector <Derived *> ??

why is the following not allowed :

vector <Base *vec_of_base;
vector <Derived *vec_of_derived;
vec_of_base = vec_of_derived;

Note : The following is allowed :

Base *base_ptr;
Derived *derived_ptr;
base_ptr = derived_ptr;

How do things change when we use a vector ?

Jan 23 '07 #1
16 2359
call_me_anything wrote:
why is the following not allowed :

vector <Base *vec_of_base;
vector <Derived *vec_of_derived;
vec_of_base = vec_of_derived;

Because vector<Derived*is not derived from vector<Base*>. In fact,
considering the possibility of template specialization, vector<Derived*>
may be wildly different than vector<Base*>.
>
Note : The following is allowed :

Base *base_ptr;
Derived *derived_ptr;
base_ptr = derived_ptr;

How do things change when we use a vector ?
It's not unique to a vector. A relation between the template parameters
does not imply any relationship between the template classes.
Jan 23 '07 #2
"call_me_anything" <sg***@yahoo.comwrote in message
news:11*********************@q2g2000cwa.googlegrou ps.com...
why is the following not allowed :

vector <Base *vec_of_base;
vector <Derived *vec_of_derived;
vec_of_base = vec_of_derived;
It's hard to understand how one would implement such a feature without also
allowing

vector<Xvx;
vector<Yvy;

vx = vy;

whenever it is possible to convert Y to X. Such assignments could be
allowed in principle, but they can also be hazardous and inefficient. If
you want to achieve that effect, you can do so fairly easily:

vec_of_base.assign(vec_of_derived.begin(), vec_of_derived.end());

Please note that this question is completely different from the commonly
asked question about why it is not possible to convert a vector<Derived>* to
a vector<Base>*.
Jan 23 '07 #3

Andrew Koenig wrote:
"call_me_anything" <sg***@yahoo.comwrote in message
news:11*********************@q2g2000cwa.googlegrou ps.com...
why is the following not allowed :

vector <Base *vec_of_base;
vector <Derived *vec_of_derived;
vec_of_base = vec_of_derived;

It's hard to understand how one would implement such a feature without also
allowing

vector<Xvx;
vector<Yvy;

vx = vy;

whenever it is possible to convert Y to X.
You could use a combination of enable_if, is_pointer, and
is_base_of...maybe something like so:

template < typename other_val_type >
enable_if
<
mpl::and_
<
is_pointer<value_type>
, is_pointer<other_val_type>
, is_base_of<value_type, other_val_type>
>
, vector &
>
operator = ( vector<other_val_typeconst & right)
{
....??
}

Jan 23 '07 #4
On Jan 23, 8:31 pm, "call_me_anything" <s...@yahoo.comwrote:
why is the following not allowed :

vector <Base *vec_of_base;
vector <Derived *vec_of_derived;
vec_of_base = vec_of_derived;
...
How do things change when we use a vector ?
Well, and if we call these types not Base and Derived, having the
assignment base=derived being correct, will these vectors be equal,
without derivation relationships? We will have to do element-by-element
assignment anyway.

Although in this case there should work a trick, based on the equality
of Base* and Derived* entities -- they are pointers with same size. I'm
not quite sure whether it's correct, but i was once told to try
reinterpret_cast vec_of_base. Though, having been never tried out by
me, it seems reasonable.

Jan 24 '07 #5
call_me_anything wrote:
why is the following not allowed :

vector <Base *vec_of_base;
vector <Derived *vec_of_derived;
vec_of_base = vec_of_derived;

Note that the following is legal:

vector<Base *vec_of_base;
vector<Derived *vec_of_derived;
vec_of_base.assign(vec_of_derived.begin(), vec_of_derived.end());

Admittedly it's much wordier than your version, but it compiles and does
what you want.

Joe Gottman
Jan 24 '07 #6
why is the following not allowed :
>
vector <Base *vec_of_base;
vector <Derived *vec_of_derived;
vec_of_base = vec_of_derived;
I became curious enough to check it for myself.

vec_of_base=*reinterpret_cast<vector<Base*>*>(&vec _of_derived)

This does work, at least under MSVS.

Jan 24 '07 #7
"Pavel Shved" <Pa*********@gmail.comwrote in message
news:11**********************@m58g2000cwm.googlegr oups.com...
I became curious enough to check it for myself.
vec_of_base=*reinterpret_cast<vector<Base*>*>(&vec _of_derived)
This does work, at least under MSVS.
If it works, it does so only by coincidence.
Jan 24 '07 #8


On Jan 24, 8:54 am, "Andrew Koenig" <a...@acm.orgwrote:
vec_of_base=*reinterpret_cast<vector<Base*>*>(&vec _of_derived)
If it works, it does so only by coincidence.
Yes, coincidence is the exact reason why it does work. ;-) vector
<Base*and vector <Derived*are be byte-to-byte equal.

Jan 24 '07 #9


On Jan 23, 1:33 pm, "Noah Roberts" <roberts.n...@gmail.comwrote:
whenever it is possible to convert Y to X.You could use a combination of enable_if, is_pointer, and
is_base_of...maybe something like so:

template < typename other_val_type >
enable_if
<
mpl::and_
<
is_pointer<value_type>
, is_pointer<other_val_type>
, is_base_of<value_type, other_val_type>
>
, vector &
// HERE
operator = ( vector<other_val_typeconst & right)
{
...??

}
I don't normally respond to people that email me instead of posting to
the group but I decided in this case I would. Someone asked me two
questions:

1) Are these standard components or did I just make them up?

It is a combination of standard stuff and things that are found in
certain boost libraries. Some of it, including the is_pointer and
is_base_of traits, will be in the next standard. These are basic
metaprogramming techniques but if you've never seen metaprogramming it
might be rather difficult to understand.

2) Where does the last go?

Apparently google groups removed it. It should be on the line after
vector& and before "operator", I put it back.

Now, newsgroup etiquette says you post your replies to the group, not
the user. This is not only because it might be considered rude but so
that others can see the answer...now you know.

Jan 24 '07 #10
* Pavel Shved:
>
On Jan 24, 8:54 am, "Andrew Koenig" <a...@acm.orgwrote:
>>vec_of_base=*reinterpret_cast<vector<Base*>*>(&v ec_of_derived)
>If it works, it does so only by coincidence.

Yes, coincidence is the exact reason why it does work. ;-) vector
<Base*and vector <Derived*are be byte-to-byte equal.
Sorry, that's incorrect.

One might easily get the impression that these vectors would be
effectively equal because both are vectors of class type pointers, and
those pointer values are the same size, and so, unless the vector
implementation against all odds contains some unwarranted hacking, they
have the exact same /memory layout/.

But consider that reinterpret_cast<Base*>(pDerived) and
static_cast<Base*>(pDerived) do not always yield the same result.

So what you have is simply undefined behavior.

If it works, it works by coincidence, for a particular pair of Base and
Derived classes.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jan 24 '07 #11
"call_me_anything" <sg***@yahoo.comwrote:
why is the following not allowed :

vector <Base *vec_of_base;
vector <Derived *vec_of_derived;
vec_of_base = vec_of_derived;

Note : The following is allowed :

Base *base_ptr;
Derived *derived_ptr;
base_ptr = derived_ptr;

How do things change when we use a vector ?
Things change because the above doesn't work for arrays, thus it doesn't
work for vectors. As an example:

struct Base {
int x;
};

struct Derived : Base {
int y;
};

int main() {
Derived* derivedPtr = new Derived[2];
derivedPtr[0].y = 10;
Base* basePtr = derivedPtr;
basePtr[1].x = 0;
assert( derivedPtr[0].y == 10 );
delete [] derivedPtr;
}

The assert in the above will probably fail, even though it shouldn't.

The fact that the vector code fails to compile is yet another example of
why vectors are better than bald arrays.
Jan 24 '07 #12
"Pavel Shved" <Pa*********@gmail.comwrote in message
news:11*********************@l53g2000cwa.googlegro ups.com...
>If it works, it does so only by coincidence.
Yes, coincidence is the exact reason why it does work. ;-) vector
<Base*and vector <Derived*are be byte-to-byte equal.
You think so? How about trying it with these classes:

struct Base { };

struct Derived: virtual Base { };

Now the internal representations of a Derived* and a Base* pointing to the
same object are different.

As I said, if it works, it does so only by coincidence.
Jan 24 '07 #13
"Daniel T." <da******@earthlink.netwrote in message
news:da****************************@news.west.eart hlink.net...
"call_me_anything" <sg***@yahoo.comwrote:
>why is the following not allowed :

vector <Base *vec_of_base;
vector <Derived *vec_of_derived;
vec_of_base = vec_of_derived;

Note : The following is allowed :

Base *base_ptr;
Derived *derived_ptr;
base_ptr = derived_ptr;

How do things change when we use a vector ?

Things change because the above doesn't work for arrays, thus it doesn't
work for vectors. As an example:

struct Base {
int x;
};

struct Derived : Base {
int y;
};

int main() {
Derived* derivedPtr = new Derived[2];
derivedPtr[0].y = 10;
Base* basePtr = derivedPtr;
basePtr[1].x = 0;
assert( derivedPtr[0].y == 10 );
delete [] derivedPtr;
}

The assert in the above will probably fail, even though it shouldn't.

The fact that the vector code fails to compile is yet another example of
why vectors are better than bald arrays.
This argument would be better if the OP wanted to assign a vector<Derived>
to a vector<Base>. But he doesn't want that, he wants to assign a
vector<Derived*to a vector<Base*>. But aside from that, a vector
assignment will create a _copy_, so pointer magic has got nothing to do with
it - you can perfectly copy an array of Deriveds to an array of Base. You
can't use the assignment operator for it, but std::copy could cope with it
just fine. Of course, you're slicing the Deriveds, but hey, if that's what
you want you can get it ;).

Now, the reason why you can't assign a Derived** to a Base**, is because
then you could let a Derived* point to something other than a Derived
(similar with const).

Jan 24 '07 #14


On Jan 23, 11:00 pm, "Alf P. Steinbach" <a...@start.nowrote:
* Pavel Shved:
On Jan 24, 8:54 am, "Andrew Koenig" <a...@acm.orgwrote:
>vec_of_base=*reinterpret_cast<vector<Base*>*>(&ve c_of_derived)
If it works, it does so only by coincidence.
Yes, coincidence is the exact reason why it does work. ;-) vector
<Base*and vector <Derived*are be byte-to-byte equal.Sorry, that's incorrect.

One might easily get the impression that these vectors would be
effectively equal because both are vectors of class type pointers, and
those pointer values are the same size, and so, unless the vector
implementation against all odds contains some unwarranted hacking, they
have the exact same /memory layout/.

But consider that reinterpret_cast<Base*>(pDerived) and
static_cast<Base*>(pDerived) do not always yield the same result.
This is why I didn't fill out the body of my assignment op hack.

Is this code valid?

Derived * d = new Derived[20]();
Base * b = static_cast<Base*>(d);

b[10]->f();

delete [] b;

For all possible constructions of Base and Derived? (assuming a
parental is-a relation)

I believe it should be, but in all honesty I've never had to do
anything remotely like this.

Jan 24 '07 #15
"Noah Roberts" <ro**********@gmail.comwrote in message
news:11**********************@v45g2000cwv.googlegr oups.com...
Is this code valid?

Derived * d = new Derived[20]();
Base * b = static_cast<Base*>(d);

b[10]->f();

delete [] b;

For all possible constructions of Base and Derived? (assuming a
parental is-a relation)
No way.

It will usually work in practice provided that Base has a virtual destructor
and sizeof(Base) == sizeof(Derived), but not otherwise. Moreover, it's not
guaranteed to work in any circumstances.
Jan 24 '07 #16


On Jan 24, 11:23 am, "Andrew Koenig" <a...@acm.orgwrote:
"Noah Roberts" <roberts.n...@gmail.comwrote in messagenews:11**********************@v45g2000cwv.g ooglegroups.com...
Is this code valid?
Derived * d = new Derived[20]();
Base * b = static_cast<Base*>(d);
b[10]->f();
delete [] b;
For all possible constructions of Base and Derived? (assuming a
parental is-a relation)No way.

It will usually work in practice provided that Base has a virtual destructor
and sizeof(Base) == sizeof(Derived), but not otherwise. Moreover, it's not
guaranteed to work in any circumstances.
Yeah, nm. I knew that. Wasn't thinking clearly. Meant something more
along the lines of Base ** ptr = static_cast<Base**>(dptr), which is
not valid at any rate. If there was a way for the vector to swap it's
buffer pointer with the other vector there might be a benifit to op=
for base/derived vectors but I don't see that as being reliably
possible.

Jan 24 '07 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Weston C | last post by:
I'm trying to get the href attribute from the base tag in the document head. The following does not seem to work... any ideas what I'm doing wrong? if(!(document.getElementsByTagName) ||...
2
by: CD | last post by:
Is this possible: class base; class derived; //:public base vector <base*> bList; vector<derived*> dList; //add some derived class pointer entries to dList;
7
by: Frank Bormann | last post by:
Hi guys, I'm a C++ beginner. I was wondering if there is a generalized vector base class, through which I could pass a pointer to any kind of vector to a function, regardless of what type of...
2
by: Siemel Naran | last post by:
This code fails compile std::auto_ptr<Base> f() { std::auto_ptr<Derived> out(new Derived()); return out; } There is ambiguity between a templated constructor and templated operator...
3
by: Gilbert Saint-Flour | last post by:
Hello: I have this one line of PHP code which I'd like to convert to Javascript. The PHP code conditionally issues a BASE statement when the html page is called with a frame name, e.g....
1
by: Chris Sharman | last post by:
I'm seeing quite a few 404 errors, all from an agent/browser which calls itself "Mozilla/4.0 (compatible; BorderManager 3.0)". They appear to be from a built page like...
3
by: SJ | last post by:
Hi, I have a problem with the HTML <base> element, URL re-writing and Postback. We are using URL re-writing on the server, and I'd like to use the base element to make the URLs in the ASPX pages...
3
by: yan | last post by:
Hello everybody, I am new so this is the occasion to say hello to everybody. I have a problem with absolute/relative paths. I have to create a static documentation in html for a project and I have...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.