c++ - 在没有枚举和开关的情况下调用许多 vector 之一的函数

标签 c++ class templates template-meta-programming c++20

我有一个类,其中包含几个不相关类的 vector 。

class Class0 {};
class Class1 {};
class Class2 {};

enum class RemoveFromVector : uint8_t { CLASS0 = 0, CLASS1 = 1, CLASS2 = 2 };

class C
{
public:
   std::vector<Class0> c0s;
   std::vector<Class1> c1s;
   std::vector<Class2> c2s;

   void RemoveFromVector(const RemoveFromVector RFV, const int Index)
   {
      // I'd like to replace this switch with something that's compile-time
      switch ((uint8_t)RFV)
      {
      case 0: c0s.erase(c0s.begin() + Index); break;
      case 1: c1s.erase(c1s.begin() + Index); break;
      case 2: c2s.erase(c2s.begin() + Index); break;
      default: break;
      }
   }
};

int main()
{
   C c;
   c.c0s.push_back(Class0());
   c.c1s.push_back(Class1());
   c.c1s.push_back(Class1());
   c.c1s.push_back(Class1());
   c.c2s.push_back(Class2());

   // this should remove the last element from C.c1s
   c.RemoveFromVector(RemoveFromVector::CLASS1, 2);
}

我将如何编写一个函数,在运行时基于枚举(或int)从一个 vector 中删除一个元素,而不必编写一个具有的开关每个 vector 的情况?

换句话说,我正在寻找一种方法来推断在编译时静态调用哪个 vector erase(),然后在运行时调用它。正确的术语可能是“静态调度”,但我不完全确定。

最佳答案

您应该使代码尽可能简单。根据当前显示的代码,对于以后在代码库上工作的每个开发人员来说,它都是简单易读的。

其次,通过 std::vectors 的内部存储无论如何都会在运行时执行此任务。因为,std::vector 发生的大多数操作都是运行时开销,因为它们在运行时分配内存并管理它。因此,您不能为 std::vector::erase 做任何编译时工作。


话虽这么说,如果你坚持避免 switch 语句,并带来模板复杂性,下面是一个,它仍然会有一种使用 if constexpr, vector 删除发生在运行时。

#include <type_traits> // std::is_same_v

class C
{
   template<typename ClassType>
   auto& getVectorOf() /* noexcept */
   {
      if constexpr (std::is_same_v<ClassType, Class0>) return c0s;
      else if constexpr (std::is_same_v<ClassType, Class1>) return c1s;
      else if constexpr (std::is_same_v<ClassType, Class2>) return c2s;
   }
public:
   std::vector<Class0> c0s; // recommended to be private!
   std::vector<Class1> c1s;
   std::vector<Class2> c2s;

   template<typename ClassType>
   void RemoveFromVector(const std::size_t index) /* noexcept */
   {
      // some index check!
      auto& vec = getVectorOf<ClassType>();
      vec.erase(vec.begin() + index);
   }
};

像这样调用函数

C c;
// fill the vectors
c.RemoveFromVector<Class0>(0);
c.RemoveFromVector<Class1>(2);
c.RemoveFromVector<Class2>(0);

( See a Demo Online )

关于c++ - 在没有枚举和开关的情况下调用许多 vector 之一的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63879792/

相关文章:

C++ - 如何在函数声明中使用模板 typedef 解决方法?

c++将unique_ptr作为对另一个函数的引用传递

c++ - 将 RGB 图像保存为 PPM 格式

C++ 调试帮助内存泄漏

c++ - 使用 .natvis 文件在 VS Code 中可视化 C++ 对象

python - 如何定义一个 super 强大的class风格的dict对象?

C++,使用模板编程的术语/习语

python - 访问另一个 tkinter 类的输入字段值

PHP:如何在类中创建动态变量

html - 寻找像这样的 wordpress 的三面板 css 布局