c++ - vector 元组并向后推

标签 c++ c++11 templates c++14

我有一个 vector 元组,我想将初始化列表中的每个值push_back() 放入“vector 元组”中的相应 vector 中。代码中的 create() 函数是我想要执行此操作的地方。

template<typename...Fields>
class ComponentManager
{
  using Index = int;
public:
  /**
   * Provides a handle to a component
   **/
  struct ComponentHandle {
    static constexpr Index Nil = -1;
    bool nil() { return index == Nil; }
    const Index index;
  };

  ComponentHandle lookup(Entity e) { 
    return ComponentHandle{get(m_map,e,-1)}; 
  }

  template<int i>
  auto get(ComponentHandle handle) {
    return std::get<i>(m_field)[handle.index];
  }

  ComponentHandle create(Entity e, Fields ...fields) {
    m_entity.push_back(e);
    // m_fields.push_back ... ???
  }

private:
  std::vector<Entity>                m_entity;
  std::tuple<std::vector<Fields>...> m_field;
  std::map<Entity,Index>             m_map;
};

例子:

Entity e1, e2;
ComponentManager<int,float,int> cm{};
cm.create(e1, 42, 1337.0, 99);
cm.create(e2, 84, 2674.0, 198);
// Resulting contents of cm.m_field tuple
// { 
//    vector<int>   [ 42, 84 ], 
//    vector<float> [ 1337.0, 2674.0 ]
//    vector<int>   [ 99, 198 ]
// }

最佳答案

这可能不是很明显,但在 C++ 中解包元组的方法是使用 std::apply()。使用 C++17,这很简单:

void create(Entity e, Fields ...fields) {
    m_entity.push_back(e);
    std::apply([&](auto&... vs) {
       (vs.push_back(fields), ...);
    }, m_field);
}

对于 C++14,我建议您自己实现 apply()(它是一个 short function ),然后您需要使用 expander trick而不是使用折叠表达式:

void create(Entity e, Fields ...fields) {
    m_entity.push_back(e);
    not_std::apply([&](auto&... vs) {
       using swallow = int[];
       (void)swallow{0, 
           (vs.push_back(fields), 0)...
           };
    }, m_field);
}

在 C++11 中,大部分内容都适用,除了我们不能使用通用 lambda 并且实现 std::apply 比链接引用中的更冗长(但并不更复杂) .值得庆幸的是,除了让代码更短之外,我们实际上不需要做任何事情——我们知道所有的 vector 类型:

void create(Entity e, Fields ...fields) {
    m_entity.push_back(e);
    not_std::apply([&](std::vector<Fields>&... vs) {
       using swallow = int[];
       (void)swallow{0, 
           (vs.push_back(fields), 0)...
           };
    }, m_field);
}

关于c++ - vector 元组并向后推,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41925528/

相关文章:

c++ - 我如何在 FreeBSD 上禁用 ASLR?

c++ - 为什么不捕获 `std::promise::~promise` 中已经传播的异常

c++ - 如何合并两个 mpl map 生成新 map ?

templates - 新 api 应用程序资源的 Azure 资源模板

c++ - 简单参数包扩展 : expected ';'

c++ - 非成员运算符重载应该放在哪里?

c++ - 在C++中将对象写入二进制文件

c++ - 从类模板派生的类的通用函数

c++ - 在 C++ 中如何切换到另一个目录?

c++ - 如何强制从重写方法中调用重写方法基础方法?