【发布时间】:2019-03-04 17:23:13
【问题描述】:
我面临一个问题,我必须生成大量代码,所有代码都非常相似,我想知道是否有任何方法可以模板化。
假设我有这种类型的结构
template <typename ...NodeKindTs>
struct Element{
std::tuple<NodeKindTs...> nodes;
}
我有一个整数向量,它将一个节点与另一个节点相关联,还有一个枚举向量,它表示每个节点是哪种类型。种类可以是 A、B 或 C。
enum class Kind {A,B,C};
std::vector<int> relationShip;
std::vector<Kind> kind;
例如,如果我有
relationShip = {1,2,-1};
kind = {A,B,A}
表示第一个节点属于 A 类,并且与属于 B 类的第二个节点相关。你明白了。
现在,我必须创建元素并将它们插入到向量中,具体取决于每个节点和关系的 NodeKind。此元素由多达 6 个 NodeKinds 模板化。为了解决这个问题,我需要一个巨大的 if 来检查每个节点的 Kind 然后调用 Element ctor。
对于 2 NodeKinds 的情况,这意味着做类似的事情
if (node1.type == A && node2.type == A) {
auto &simNode1 = containerOfAs(node1.id);
auto &smiNode2 = containerOfAs(node2.id);
insertElement(elementFactory(simNode1, simNode2));
}
if (node1.type == A && node2.type == C)
{
auto &simNode1 = containerOfAs(node1.id);
auto &smiNode2 = containerOfCs(node2.id);
insertElement(elementFactory(simNode1, simNode2));
}
if (node1.type == B && node2.type == C)
{
auto &simNode1 = containerOfBs(node1.id);
auto &smiNode2 = containerOfCs(node2.id);
insertElement(elementFactory(simNode1, simNode2));
}
...
inserElement 是我创建的一个元函数,如果适合从容器列表中插入元素,它会将元素插入容器中。
对于这 2 种情况,这最多需要 9 个 if。对于第 3 种情况,它需要 27 个 ifs,而对于第 6 种情况,它需要 729 个 ifs。我真的不想对它们进行编码。
知道如何解决这个问题吗?
谢谢!
【问题讨论】:
-
听起来有点像在 Boost Units 中解决类似问题的方式。 boost.org/doc/libs/1_69_0/doc/html/boost_units.html
-
您仍然可以使用
std::variant让它为您完成组合...但我担心它会减慢编译速度。 -
@Jarod42 你将如何使用 std::variant 来解决这个问题。我一直在思考,但没有找到答案。
-
@Eljay 我一直在查看 Boost.Units 的文档,但我没有发现类似的问题。你能多指点我吗?谢谢!
-
Boost Units 对 SI 单位的各种排列使用参数化模板。也许我误解了您面临的问题。
标签: c++ enums combinations metaprogramming