Vector中的Vector,以ENUM作为ID

Vector in Vector with ENUM as ID

本文关键字:Vector 作为 ID ENUM 中的      更新时间:2023-10-16

我想创建一个向量的向量与一个关键,这应该是一个Enum。

伪代码:

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

谁能给我一个提示,我怎么做这个很简单?有没有比vector更好的数据结构?

我想把点云中的点分割成它们各自的颜色代码。

如果您的enum值是连续的,只需将它们转换为std::size_t

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

现在,您必须确保MyContainer已经调整大小,因为vector s在它里面。at不填充容器,它只是检查边界,如果超出vector的边界就抛出。

现在,由于你的点集是固定的,我们可以去掉一个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);

另一种选择是将最外层的容器替换为std::unordered_map,但这将更慢,效率更低。std::map会更慢。

如果您使用enum而不是enum class,您将保存上面std::size_t的一些强制转换,但我建议不要这样做。unordered_map需要一个快速散列:

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

但是,我还是不建议这样做。

最后一个选项是围绕arrayvector编写一个自定义容器包装器,为您执行std::size_t强制转换。只有当我打算把它作为某种类型的库发布时,或者当我感到无聊时,我才会费心做这种事情。

使用std::map<Color, std::vector<int>>代替。

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
}

现场演示

vector是序列容器。如果您想将条目映射到某种键,而不必是连续的,那么映射可能是一个更好的主意。