能给我一张“票”吗;“类型的类型”;在C++;? 我对C++非常陌生,但我一直在尝试在锁定期间多样化我的技能集。 我正在尝试使用SFML编写一个基于节点的声音处理工具。我希望有一个包含所有节点输入和输出的结构。然而,我显然无法将任何类型连接在一起。我希望做一些类似于Blender对其节点类型所做的事情。 下面的屏幕记录显示了我的意思:绿色输出类型与其他输入类型不兼容。
我认为能给我一张“票”吗;“类型的类型”;在C++;? 我对C++非常陌生,但我一直在尝试在锁定期间多样化我的技能集。 我正在尝试使用SFML编写一个基于节点的声音处理工具。我希望有一个包含所有节点输入和输出的结构。然而,我显然无法将任何类型连接在一起。我希望做一些类似于Blender对其节点类型所做的事情。 下面的屏幕记录显示了我的意思:绿色输出类型与其他输入类型不兼容。 ,c++,sfml,C++,Sfml,我认为struct NodeInOut可能是这个问题的有用解决方案:每当我创建一个新节点时,我都会分配一个类型,在将节点连接在一起的逻辑中,我确保不兼容的类型不可连接。但是,无论何时创建新节点定义,我都需要传入一个类型 我对Node类的想法是,它的结构有点像这个匆忙制作的图 有没有人对如何做到这一点有什么想法,或者如何以不同的方式构建它,使其不成为问题 除了SFML样板文件之外,我还没有编写任何代码。是的,您可以有一个“类型的类型” 但是,请注意,用户在运行时连接节点。因此,这是一个运行时问题
struct NodeInOut
可能是这个问题的有用解决方案:每当我创建一个新节点时,我都会分配一个类型,在将节点连接在一起的逻辑中,我确保不兼容的类型不可连接。但是,无论何时创建新节点定义,我都需要传入一个类型
我对Node类的想法是,它的结构有点像这个匆忙制作的图
有没有人对如何做到这一点有什么想法,或者如何以不同的方式构建它,使其不成为问题
除了SFML样板文件之外,我还没有编写任何代码。是的,您可以有一个“类型的类型”
但是,请注意,用户在运行时连接节点。因此,这是一个运行时问题,而不是编译时可以解决的问题
换句话说,只需使用包含节点接受/发送的任何类型的运行时值,并根据需要对其进行比较。如果我正确理解了这个问题,类似这样的方法应该可以:
- 特定节点继承自抽象
类节点
包含纯虚拟函数,用于列出输入/输出点:类节点
virtual std::size_t InputCount() const = 0; virtual const Input &GetInput(std::size_t i) const = 0; Input &GetInput(std::size_t i) {return const_cast<Input &>(std::as_const(*this).GetInput(i));} virtual std::size_t OutputCount() const = 0; virtual const Output &GetOutput(std::size_t i) const = 0; Output &GetOutput(std::size_t i) {return const_cast<Output &>(std::as_const(*this).GetOutput(i));}
可能类似于virtualstd::size\t InputCount()const=0; 虚拟常量输入&GetInput(std::size\u ti)常量=0; Input&GetInput(std::size_t i){return const_cast(std::as_const(*this).GetInput(i));} 虚拟std::size\u t OutputCount()常量=0; 虚拟常量输出&GetOutput(std::size\u ti)常量=0; Output&GetOutput(std::size_t i){return const_cast(std::as_const(*this).GetOutput(i));}
virtualvoidupdate()=0代码>,
等DrawGui
- 从
节点派生的类将
和Input
对象作为成员,并重写Output
和GetInput
以返回这些成员 (额外好处:您可以使用反射库(例如)自动生成函数。)GetOutput
必须以某种方式指向它所连接的类输入
,可能是通过将指针(输出
?)存储到拥有连接的std::weak_ptr
输出的
,以及节点中该节点
输出的索引
应至少包含类输出
浮点值代码>(或其他,取决于您希望支持的值)。可能您需要在其中存储一个连接的
输入的列表(其中每个元素都是指向
节点的指针,加上其中
输入的索引)
- 每个节点都是(最终的,不是虚拟的)
类的成员节点
- 这个
类有一个节点
和一个std::vector
,表示节点的每个输入和输出(如果您足够努力,它们可能会成为常量)std::vector
- 您添加了一个名为
的私有变量,该变量的类型为update
或等效变量(例如,您可以使用lambdas),它是一种用户定义的更新方法,用于根据输入设置输出,并添加了一个名为std::function
的公共函数,这是一个调用此节点的update
和以下节点的update
的函数(因为它们也需要更新)update
- 然后,对于
s,您需要一个函数来设置值(可能是一个模板函数?然后检查类型是否正确并获得一个兼容的类型,可能使用输出
s来存储值),以及连接到它的所有std::variant
s的列表(因此,输入
可能?或者您也可以用std::vector
替换std::weak\u ptr
)节点*
- 至于输入,您需要能够将它们连接到一个
,因此输出
或输出*
应该可以工作,但由于您需要能够拥有常量,您可以:std::weak_ptr
- 还有一个
来存储默认值,或者std::variant
- 您可以创建新的“不可见”
s,其中没有输入,每个悬空输入有一个输出,或者节点
- 为每个可见的节点创建一个不可见的
,该节点没有输入,输出的数量与目标节点的输入数量相同(并将它们一一连接)节点
这也许(可能)不是最好的解决方案,但至少它应该能起作用。我不是这个解决方案的真正粉丝,首先是因为
const\u cast
s(尽管经过更多的思考,我想不出一个方法来纠正它……),其次是因为弱ptr
:为什么不是简单的输出*
?输出还应该记住输入*
的向量,而不是连接的节点和输入索引(OP想要连接到多个输入…。@rajdakin“弱ptr
:为什么不是简单的输出*
?”如果它是一个弱\u ptr
,那么删除一个节点很容易:只需删除它,连接到它的节点就会自动断开连接。但是如果它是一个普通指针,则必须迭代所有连接的节点并手动断开连接(考虑到