如何在编译时建立有向图?

时间:2014-04-14 11:29:41

标签: c++ c++11 compile-time

我想在编译时在C ++ 11中构建有向图。

示例:我有一些线程和队列,想要建立起来:

+-------+            +---------+            +-------+
| f_gen | -> QGen -> | f_check | -> QOut -> | f_out |
+-------+            +---------+    ^       +-------+
                          |         |
                         \|/        |
                          |         |
                        QProc       |
                          |         |
                         \|/        |
                          |         |
                     +-----------+  |
                     | f_process | /
                     +-----------+

请注意,这只是一个例子:解决方案应该处理 每个节点/边缘类型的有向图。

我想写它可能就像:

make_directed_graph<Queue, Thread>(
// Queues
{
   // ID, Type of Queue, queue size
   { 0, std::string, 100 }, // QGen
   { 1, int, 250 },         // QProc
   { 2, std::string, 500 }  // QOut
},
// Threads
{ 
   // Fn, thread cnt, in queues, out queues
   { f_gen, 5, {}, { qref(0) } }, // ID 1: QGen 
   { f_check, 30, { qref(0) }, { qref(1), qref(2) }}, // IDs of queues
   { f_process, 75, { qref(1) }, { qref(2) }},
   { f_out, 12, { qref(2) }, {} }
});

请注意,这只是一个想法 - 任何其他可能性 写这篇文章对我来说很好。

我设法实现了make_tree功能。 它可以像

一样使用
make_tree< arexp, int >(
     { '+', { 1, 2, { '*', { 3, 4, 5 } } } } )

这里有一个很大的区别:可以创建节点和边缘 苍蝇' - 没有必要参考任何现有的。

有向图的最大问题是如何引用一个对象/ 前面定义的结构/部分。喜欢:如何参考一个 定义线程时的队列(或反之)。

我的问题:

  1. 是否可以在编译时定义有向图?
  2. 如果是的话,请你给我一个如何实施它的提示?

2 个答案:

答案 0 :(得分:1)

它通常是可能的,因为您使用指针识别对象,并且这些指针是有效的非类型模板参数。

Queue<std::string> QGen(100); // No need for an ID, we have &QGen.
// We  *do* need to pass the Queue type to figure out the type of &QGen.
Thread<void, nullptr, std::string, &QGen> f_gen(5);

当然,您无法通过这种方式定义循环图。

答案 1 :(得分:0)

我认为我已经向解决方案迈进了一步(但尚未完成):

我的错误在于没有必要直接写下图表本身,而是某种表示。以下源代码至少编译:

directed_graph const dg(
  make_directed_graph<Node, Edge>(
     {
        { 1, "qgen" },
        { 2, "qproc" },
        { 3, "qout" },
        { "fgen", {}, { 1 } },
        { "fcheck", { 1 }, { 2, 3 } },
        { "fproc", { 2 }, { 3 } },
        { "fout", { 3 }, {} }
     }));

给出make_directed_graph的以下定义和相应的initializer_list:

class NodeRef {
public:
   NodeRef(int nid);
};

class digraph_initializer {
public:
   digraph_initializer(int id, std::string const & s);
   digraph_initializer(
      std::string const & s,
      std::initializer_list< NodeRef > const nr_in,
      std::initializer_list< NodeRef > const nr_out);
};

class directed_graph {
};

template< typename TNode, typename TEdge >
directed_graph make_directed_graph(
   std::initializer_list<digraph_initializer> const & dgi);

还有一些开放点:

  1. 如何确保只有在定义边时才能引用边?
  2. 建立真实的&#39;编译时来自initializer_list的图表。
  3. 添加用于处理/初始化任意节点/边的模板(参数)。