3

I have an array std::vector<int> and an enum class Foo : int. Is there a better way to cast or convert than a reinterpret_cast?

std::vector<int> v;
auto& c = *reinterpret_cast<std::vector<Foo>*>(&v);
Daniel Stephens
  • 2,371
  • 8
  • 34
  • 86
  • Why cast the container instead of the elements? I am not sure you can use `reinterpret_cast` the way you are in this example. – cplusplusrat Sep 25 '19 at 23:11
  • 4
    If `reinterpret_cast` works, it's only because you are getting lucky. Cast when accessing individual indexes. Or make a copy of the vector and copy over each element and cast one at a time. – selbie Sep 25 '19 at 23:12
  • 4
    There is an algorithm function designed for this called `std::transform`. – PaulMcKenzie Sep 25 '19 at 23:13
  • Thanks, good to know! – Daniel Stephens Sep 25 '19 at 23:15
  • `std::vector fv; std::transform(v.begin(), v.end(), std::back_inserter(fv), [&](int n) { return n_converted_to_a_Foo;});` -- That in a nutshell is what you probably wanted. It would create a new Foo vector based on the `v` vector's contents. If this is acceptable, I could post this as an answer. – PaulMcKenzie Sep 25 '19 at 23:25
  • @PaulMcKenzie that is the *only* acceptable approach in this case. Can't use the original vector as-is, a copy must be made, otherwise the code has undefined behavior. – Remy Lebeau Sep 25 '19 at 23:40

1 Answers1

8

https://godbolt.org/z/M6ofkF

Combine a static_cast with std::transform.

#include <algorithm>
#include <vector>
#include <cassert>

enum class Foo : int {
   A = 0,
   B = 1,
   C = 2,
   D = 3,
   E = 4,
   F = 5
};

std::vector<Foo> convert(std::vector<int> const &in) {
  std::vector<Foo> out;
  out.reserve(in.size());

  std::transform(in.begin(), in.end(), std::back_inserter(out),
                 [](int n) { return static_cast<Foo>(n); });
  return out;
}

int main() {
  std::vector<int> vec{1, 2, 3, 4, 5};
  std::vector<Foo> c = convert(vec);

  assert(c[3] == Foo::E);

  return 0;
}

Reference: How to cast int to enum in C++?

Unapiedra
  • 15,037
  • 12
  • 64
  • 93
  • Very sadly, this actually does computations (as of gcc12 and Clang13) although the computations do absolutely nothing and it should be optimized to a simple copy assignment. This fact kind of makes me not want to use enums in the first place if I'm going to put them into vectors... – Adomas Baliuka Oct 12 '22 at 11:45
  • The issue with this approach is that values that do not belong to the enum get converted as well. https://godbolt.org/z/crrj6sv1f – nvd Nov 02 '22 at 22:59