我有一个 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/