c++ - 模板循环依赖 - 不同文件中的单独类

标签 c++ c++11 templates circular-dependency

首先,我想说,我知道以前曾有人问过此类问题(例如此处 Resolving a Circular Dependency between Template Classes )。

但是,这种解决方案(将声明与实现分离)仅在将两个类放入一个文件时才有效。就我而言,我有一个 StateManager 和一个 State 类,它们都相当大并且保证会增长。因此,将它们放在一个大文件中似乎对我来说并不令人满意。

这里有一些重要的代码片段:

// Forward declare the StateManager --> does not work (incomplete type)
class State
{
public:
    template <class TData>
    void RequestStackPush(ID stateId, std::shared_ptr<TData> data);
private:
    StateManager & stataManager;
}

这里是RequestStackPush()方法的实现

template<class TData>
    inline void State::RequestStackPush(ID stateId, std::shared_ptr<TData> data)
    {
        // Uses the state manager's PushState() method - here the issue with the incomplete type arises
        stateManager.PushState<TData>(stateId, data);
    }

显然,StateManager 始终使用 State 类。它创建它调用方法等,因此前向声明在这里不是解决方案。只是给你举个例子:

template<class TData>
    inline void StateManager::PushState(State::ID stateId, std::shared_ptr<TData> data)
    {
        std::unique_ptr<BasePendingChange> pendingChange = std::make_unique<PendingPushDataChange<TData>>(Push, stateId, data);
        pendingChangeQueue.push(std::move(pendingChange));
    }

目前,这两个类都在一个大文件中。首先,声明 State 类,并向前声明 StateManager,然后声明 StateManager 类,然后执行上述内容描述了 State::RequestStackPush() 方法,最后实现了所有 StateManager 模板方法。

如何将其分成两个不同的文件?

最佳答案

However, this solution (Separating the declaration from the implementation) only works when putting both classes into one file.

不,它不仅仅适用于一个文件。您始终可以通过包含子 header 来构建相同的文件。它只要求您做一些对于非模板来说不常见的事情(尽管相同的技术适用于所有内联函数定义):您需要在定义类后包含一个文件。尽管给定了标题,但标题并不限于位于文件顶部。

所以,在一个文件中:

  • 声明StateManager
  • 定义状态
  • 包含 StateManager 的定义
  • 定义依赖于StateManager定义的成员函数

其他文件中没有任何异常:

  • 包含状态的定义
  • 定义StateManager及其成员函数。

最终结果是,包含任一 header 都会按所需顺序生成相同的定义和声明。因此,这种文件分割对于限制因修改 header 之一而导致的重新编译量毫无帮助。

这可能是一个品味问题,但我总是在类的定义之后包含内联函数(包括模板和模板函数的成员)所需的定义。这样我就不用担心是否有必要这样做。

关于c++ - 模板循环依赖 - 不同文件中的单独类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47810018/

相关文章:

c++ - 将 deque 或 LIFO 容器转换为 std::vector

c++ - 使用模板时避免循环依赖问题

c++ - Apple C 模块进入 Xcode 工具链是否有时间表?

c++ - 为什么 std::future<T> 和 std::shared_future<T> 不提供成员 swap()?

c++ - 在连续内存中存储相同长度的字符串?

c++ - 模板函数中特定于类型的静态声明

c++ - 在编译时迭代过滤与谓词匹配的参数

c++ - 与通配符匹配的文件名

c++ - 将 c++ QAbstractSeries 添加到 QML 图 TableView

C++ 构造函数 : why is this virtual function call not safe?