0

Say I have two classes A and B, and a vector of class A as below:

class A {
    int foo;
    int bar;
    void someMethod();
};
class B {
    uint foo;
    uint bar;
    void someOtherMethod();
};
std::vector<A>  va;

and I want to interpret va as a vector of B, since int and uint are re-interpretable.

What is the best practice to do the re-interpretation? For example, if I want to invoke someOtherMethod() on va, I can do ((std::vector<B> *)(&va))->someOtherMethod(). But is it the best practice?

It seems to me that reinterpret_cast<std::vector<B> >(va).someOtherMethod() does NOT work.

In addition, I am working on C++03.

-- UPDATE --

Sorry for my misinterpret of my own question. Yet my question will be a lot different than this one. So I created another question here.

I will close this question soon: This question can be seen as an independent question, and I think one of the answers below is good enough to be accepted.

Community
  • 1
  • 1
Robin Hsu
  • 4,164
  • 3
  • 20
  • 37
  • *`I have two classes`* - this is too broad. **Why** do you want to cast between them? (I'm guessing: one is "their" vector and one is "yours"?) – Wolf Jun 15 '15 at 09:11
  • *"It seems to me that `reinterpret_cast >(va).someOtherMethod()` does NOT work."* - true, but you can use `reinterpret_cast*>(&va)->someOtherMethod()` (with the same risk of undefined behaviour as your C-style cast notation). Note that the risk isn't just from the layout of the types - there's also the question of aliasing - so your *" since int and uint are re-interpretable"* argument for the safety of this is faulty. – Tony Delroy Jun 15 '15 at 09:35

3 Answers3

7

Don't. Any way you think you can do it results in undefined behaviour. Create a new vector and copy over the values.

2

The program behaviour is undefined since the types are unrelated.

One solution is to write a cast operator to copy a class B instance to a class A instance. In class B, write

operator A() const
{
    A a;
    a.foo = this->foo; // ToDo - check `this->foo` is an appropriate size
    a.bar = this->bar; // ToDo - check `this->bar` is an appropriate size
    return a; // compiler will elide the value copy
}
Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • `the types are unrelated` exactly. This is one important case of misunderstood transitivity of class relationship. – Wolf Jun 15 '15 at 09:15
1

You might be able to get away with making a union type C which can be read as int or uint and making a vector of that instead.

union C {
    int s;
    uint u;
};

std::vector<C> va;

But that won't work if you need to pass it into a method that expects a vector<uint>.

In my opinion the right way to fix this is to make the method that expects a vector into a template so that it can accept any container type. Even better, make it like the STL methods and take an iterator or iterator pair.

Zan Lynx
  • 53,022
  • 10
  • 79
  • 131