Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cast all members of an std::vector

Tags:

c++

casting

c++11

class A {};
class B : public A {};
std::vector<A*> v;
// populate the vector via library api
// now I need it cast to std::vector<B*>

Cast the whole thing works:

auto vv = reinterpret_cast< std::vector<B*>& >(v)

Is there a way to avoid the unsafe cast - std::move, placement new, something?

like image 657
Vorac Avatar asked Dec 16 '25 16:12

Vorac


1 Answers

Since you don't know if the As in the original vector can be cast to Bs. Then you could use a raw loop and check with dynamic_cast each element if is convertible to B and thus populate your vector only with the "safe" elements:

for(auto &&e : v) {
  auto p = dynamic_cast<B*>(e);
  if(p) vv.push_back(p);
}

Alternatively, you could use the following template that transforms a range of arbitrary As to a range of arbitrary Bs, without worrying if in the ranges of As there are As that can't be transformed to B:

template<typename C, typename InputIterator, typename OutputIterator>
std::enable_if_t<std::is_base_of<std::remove_pointer_t<typename std::iterator_traits<InputIterator>::value_type>, 
  std::remove_pointer_t<C>>::value> 
cast_range(InputIterator first, InputIterator last, OutputIterator out) {
  while(first != last) {
    auto p = dynamic_cast<std::remove_pointer_t<C>*>(*first);
    if(p) *out = p;
    ++first;
  }
}

Live Demo

like image 82
101010 Avatar answered Dec 19 '25 06:12

101010



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!