我可以在C ++中使用“类型类型”吗?

时间:2020-08-30 08:38:02

标签: c++ sfml

我对C ++还是很陌生,但是在锁定期间,我一直在尝试使自己的技能更加多样化。 我正在尝试使用SFML编写基于节点的声音处理工具。我想要一个包含所有节点输入和输出的结构。但是,我显然无法将任何类型连接在一起。我正在寻找与Blender对其节点类型进行相似的操作。 以下屏幕录像显示了我的意思:绿色输出类型与其他输入类型不兼容。 This screen recording

我认为struct NodeInOut可能是解决此问题的有用方法:每次创建新Node时,我都会分配一个类型,在将Node连接在一起的逻辑中,请确保不兼容类型不可连接。但是,每当我创建一个新的Node定义时,我都需要传递一个类型。

我对Node类的想法是,它的结构应类似于此草草制作的图表。

this hastily made diagram

有人对如何执行此操作有任何想法,或者如何以不同的方式构造它,以至于这不是问题吗?

除了SFML样板之外,我还没有编写任何代码。

3 个答案:

答案 0 :(得分:2)

是的,您可以拥有一个“类型类型”。

但是,请注意,用户在运行时连接节点。因此,这是一个运行时问题,不是您可以在编译时解决的问题。

换句话说,只需使用包含您的节点接受/发送的任何类型的运行时值,并根据需要比较它们。

答案 1 :(得分:1)

如果我正确理解了这个问题,则应该可以执行以下操作:

  • 特定节点从抽象class Node继承。

  • class Node包含用于列出输入/输出点的纯虚函数:

    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));}
    

    可能还有诸如virtual void Update() = 0;DrawGui之类的东西。

  • Node派生的类具有InputOutput对象作为成员,并覆盖GetInputGetOutput以返回这些成员。

  • >

    (奖金:您也许可以使用magic_get之类的反射库来自动生成函数。)

  • class Input必须以某种方式指向其连接的Output,方法可能是存储指向拥有连接{的std::weak_ptr的指针(Node?) {1}}以及该Output在节点中的索引。

  • Output至少应包含class Output(或其他内容,具体取决于要支持的值)。也许您会想要在其中存储连接的float value;的列表(每个元素都是指向Input的指针以及其中的Node的索引)。

答案 2 :(得分:1)

HolyBlackCat's answer下面的评论中所述,这是我的选择:

  • 每个节点都是{final(非虚拟)/----------------------\ |This is a really long | |string that needs to b| |reak after it reaches | |a certain limit. This | |is a really long strin| |g that needs to break | |after it reaches a cer| |tain limit.This is a r| |eally long string that| | needs to break after | |it reaches a certain l| |imit. | \----------------------/ 类的成员

  • 这个Node类有一个Node和一个std::vector<Input>,它们代表节点的每个输入和输出(如果您努力尝试,它们可能会变成const)。

  • 您添加了一个名为std::vector<Output>的私有变量,该私有变量的类型为update(例如,可以有lambda),这是一种用户定义的更新方法,用于设置输出取决于输入,还有一个称为std::function<void(Node &)>的公共函数,该函数调用此节点的Update和后续节点的update(因为它们也需要更新)

  • 然后对于Update,您需要一个函数来设置值(可能是模板函数?然后检查类型是否正确并获得兼容的类型,也许使用{{1 }}来存储值),以及与其连接的所有Output的列表(也许是std::variant?或者您也可以用{{1}替换Input })

  • 对于输入,您需要能够将它们连接到一个std::vector<Node*, unsigned>,因此Node*std::weak_ptr<Node>应该都可以工作,但是由于您需要能够拥有常量,您可以:

    1. 也有一个Output来存储默认值,或者
    2. 您可以创建新的“不可见” Output*,而无需输入,并且每个悬空的输入都有一个输出,或者
    3. 您为每个可见的对象创建一个不可见的std::weak_ptr<Output>,该对象没有输入,并且输出与目标节点的输入一样多(并一对一连接)。

这可能(不是)最好的解决方案,但至少应该可以。