Question

I would like to create a Vector of Vectors with a key, which should be an Enum.

Pseudo-Code:

MyContainer.at(Color::Red).at(3)

Can someone give me a clue, how i would do this very simple? Is there a better datastructure then vector?

I would like to segment Points in a Point-Cloud to their respective color-codes.

Was it helpful?

Solution

If your enum values are contiguous, simply cast them to std::size_t.

std::vector<std::vector<double>> MyContainer;
// resize it
double d = MyContainer.at(std::size_t(Color::Red)).at(3)

now, you'll have to make sure MyContainer has been resized, as had the vectors inside it. at does not fill in the container, it simply checks bounds and throws if it is out of bounds on vector.

Now, as your set of points is fixed, we can do away with one vector.

enum class Color {
  Red,
  Green,
  Blue,
  count, // automatically becomes the number of elements
};
std::array< std::vector<int>, std::size_t(Color::count) > MyContainer;
MyContainer[std::size_t(Color::Red)].push_back(3);

Another alternative is to replace the outermost container with std::unordered_map, but that will be slower and less efficient. std::map will be even slower.

If you use enum instead of enum class, you'll save some of the above std::size_t casts, but I would advise against it. unordered_map needs a quick hash:

namespace std {
  template<>
  struct hash<Color> {
    std::size_t operator()(Color c) const {
      return static_cast<std::size_t>(c);
    }
  };
}

but again, I'd advise against this path.

A final option would be to write a custom container wrapper around array or vector that does the std::size_t casting for you. I would only bother doing that kind of thing if I was going to be publishing it as a library of some kind, or if I was bored.

OTHER TIPS

Use a std::map<Color, std::vector<int>> instead.

enum struct Color
{
  Red,
  Blue,
};

int main()
{
  std::map<Color, std::vector<int>> m{{Color::Blue, {10,20,30}}};
  m[Color::Red] = {1,2,3,4};

  std::cout << m[Color::Red].at(3) << '\n'; // prints 4
  std::cout << m[Color::Blue][0] << '\n';   // prints 10
}

Live demo

A vector is a sequence container. If you want to map your entries to some kind of key that does not have to be consecutive then a map might be a better idea.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top