我想在编译时在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 } } } } )
这里有一个很大的区别:可以创建节点和边缘 苍蝇' - 没有必要参考任何现有的。
有向图的最大问题是如何引用一个对象/ 前面定义的结构/部分。喜欢:如何参考一个 定义线程时的队列(或反之)。
我的问题:
答案 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);
还有一些开放点: