4
class BaseA
{
}

class B : public BaseA
{
}

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

void someFunction (void)
{
    C<B> myClass;

    // I can't seem to do this...is it not possible?
    vector<BaseA> converted = ((vector<BaseA>) myClass);
}

See comment in code for what I am trying to do.

Cheetah
  • 13,785
  • 31
  • 106
  • 190

3 Answers3

12

A vector of B isn't a vector of A even if B is an A (I assume a mixup between A and BaseA)

Try

vector<A> converted(myClass.begin(), myClass.end());

which is probably what you want to express.

(BTW inheriting from vector is bad idea in general, it isn't designed for that.)

Community
  • 1
  • 1
AProgrammer
  • 51,233
  • 8
  • 91
  • 143
  • This is an important point. Inheriting from any STL container is not a good idea because they dont have virtual destructors. use the container as a member if you must. – skimon Apr 10 '12 at 16:00
  • Your proposed solution is functionally useful, but doesn't it change the desired behaviour, since now converted is a shallow copy of myClass, rather than a reference to the same vector? – Alain Apr 10 '12 at 16:03
  • @Alain Here `converted` holds deep copies of the objects in `myClass`. In the original, if it worked, `converted` would hold deep copies of the objects in `myClass`. There is no reference in the code posted. – R. Martinho Fernandes Apr 10 '12 at 16:06
  • Well the desired behavior isn't allowed (for obvious reasons). This is the closest you'll get if you ignore just casting the iterators as needed as you're parsing the array. – Blindy Apr 10 '12 at 16:06
  • I see... I thought the purpose was for the two variables to point to the same object in memory. Maybe I've been doing C# for too long too. – Alain Apr 10 '12 at 16:07
  • Wait, are you sure it's a Deep copy? Surely not if `class T` doesn't have a copy constructor implemented? But maybe that's just an obvious given. – Alain Apr 10 '12 at 16:10
  • @Alain well, it doesn't compile in that case. But the classes in the example do have copy constructors (they're generated by the compiler). – R. Martinho Fernandes Apr 10 '12 at 16:12
  • @Alain, then this isn't possible. The cases when the memory layout would be compatible are rare (a subset of the cases where B doesn't add any data member to A). – AProgrammer Apr 10 '12 at 16:15
3

C<B> and vector<A> are completely unrelated types and you would have to explicitly define such a conversion (e.g. template <typename TargetValueType> explicit operator vector<TargetValueType> () { ... }).

If such conversion is an uncommon task, something that is not really natural to the nature of your class, it might be preferable to use a range constructor (see AProgrammer's answer).

Also: If vector is std::vector, deriving from it is not a good idea. It isn't defined as a base class, and typically you should prefer containment over derivation (as it imposes looser coupling on your clients).

Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130
0

No way no how. Imagine if you had another class, X, derived from BaseA. If you could get your converted object, you could insert instances of X in it, even though the original object wouldn't allow it. You'd be breaking the semantics of your variables.

Incidentally you can do this in Java where they have no real sense of generics, but in a strongly typed generic language like C# or C++ you won't be able to do it (with the one exception in C#, but you shouldn't use it in this case anyway).

Blindy
  • 65,249
  • 10
  • 91
  • 131
  • Covariance is not important here. The converted object is **a copy, holding (possibly sliced) copies of the originals**. Inserting `X`s into it works just fine (other than the fact that the `X`s will get sliced), because it doesn't insert anything in the original object. – R. Martinho Fernandes Apr 10 '12 at 16:01