gpt4 book ai didi

c++ - 模板和循环依赖

转载 作者:搜寻专家 更新时间:2023-10-31 01:06:29 24 4
gpt4 key购买 nike

我有以下架构问题导致 header 的循环依赖。它涉及泛型编程和 C++ 模板。所以:

  • 我已经定义了聚合在节点中的属性
  • 这些属性被定义为模板
  • 此模板的参数之一是属性处理的数据类型族
  • 每个类型族都有一个专门的属性模板:
    • 基本类型( float 、整数...)
    • 指向节点的指针
  • 数据类型族是使用元编程计算的
    • 基本类型 -> 模板参数 = 0
    • 指向节点的指针 -> 模板参数 = 1
    • 未处理的类型 -> 模板参数 = -1
  • 我的循环依赖与类型族“指向节点的指针”有关
    • 为了确定指针的类型是否为节点,我使用编译时代码检查类 ConcreteNode 是否派生自类 Node
    • 虽然要确定这一点,编译器需要知道 ConcreteNode 的声明
    • 因此,当定义包含指向 ConcretNode 的指针的属性时,我必须包含 ConcreteNode 的 header ,而不是简单地向前声明 ConcreteNode
  • 如果 ConcreteNodeA 包含一个指向 ConcreteNodeB 的指针,而 ConcreteNodeB 包含一个指向 ConcreteNodeA 的指针,这会导致问题
    • 在这种情况下,我需要在 ConcreteNodeA 的 header 中包含 ConcreteNodeB 的 header ,反之
    • 这会导致标题的循环依赖

这里有一些代码来说明这一切:

// Property.hpp
class PropertyBase
{
// Some code common to all properties.
}

template <class T, int typeFamily = TypeFamily<T>::value >
class Property : public PropertyBase
{
// Default template to catch errors.
};

template <class T>
class Property<T, 0> : public PropertyBase
{
// Data is a base type.
T* m_dataRef;

// Some basic types-specific stuff.
};

template <class T>
class Property<T*, 1> : public PropertyBase
{
// Data is a pointer to a concrete node.
T** m_dataRef;

// Some pointer to node-specific stuff.
};


// ConcreteNodeA.h
#include "ConcreteNodeB"

class ConcreteNodeA : public Node
{
protected:
Property<ConcreteNodeB*>& m_nodeB;
};


// ConcreteNodeB.h
#include "ConcreteNodeA"

class ConcreteNodeB : public Node
{
protected:
Property<ConcreteNodeA*>& m_nodeA;
};

显然我的真实代码比这更复杂:

  • 即基类型只有在它是已处理类型列表的一部分时才会被处理
  • 我没有公开用于确定一个类是否派生自另一个类的元代码
    • 我想人们愿意帮助我了解这件事
    • 不喜欢的人不应该被它拖累

有人知道我如何声明我的属性而不会出现这种循环依赖问题吗?此刻我卡住了......

谢谢!

----- 编辑 ------

以下内容

TypeFamily<T>::value

是元代码,如果 T 是受支持的基类型,则返回 0,如果 T 是指向从节点派生的类的指针,则返回 1,在其他情况下返回 -1。

----- 编辑 ------

我不能对 ConcreteNodeA 和 ConcreteNodeB 使用前向声明,因为在这种情况下,编译器无法“理解”从 Node 派生的 ConcreteNodeA 和 ConcreteNodeB。因此 TypeFamily::value 将返回 -1,而不是 1。因此,所选模板将是默认的“捕获错误”模板,而不是我想要的模板 (typeFamily == 1)。

----- 编辑 ------

Node 知道 Property,因为它聚合了它们。它看起来像这样:

#include "Property.hpp" // This file also contains the declaration for PropertyBase.

class Node
{
private:
std::vector<PropertyBase*> m_props;
}

最佳答案

改用前向声明:

具体节点A.h:

class ConcreteNodeB;

class ConcreteNodeA : public Node
{
protected:
Property<ConcreteNodeB*>& m_nodeB;
};

具体节点B.h:

class ConcreteNodeA;

class ConcreteNodeB : public Node
{
protected:
Property<ConcreteNodeA*>& m_nodeA;
};

关于c++ - 模板和循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20730837/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com