模板化功能导致循环包含

时间:2016-05-15 04:13:09

标签: c++ c++11

我有一个棘手的循环包含问题,我不知道如何解决。总结一下:

  

IApp继承自Component
  Component在其头文件中实现了一个使用IApp::registerForEvent

的模板化函数

我可以使用哪种技巧或方法来修复/避免这种循环包含?

class Component;
class IApp;

class Component
{
    IApp* app;

    // Error: Invalid use of incomplete type 'class IApp'
    template<typename T>
    void registerEvent(const int& evtId, Status (T::*func) (int))
    {
        auto res = std::bind(func, (T*)this, std::placeholders::_1);
        app->registerForEvent(evtId);
    }
};

class IApp : public Component
{
public:
    void registerForEvent(const int& evtId)
    {
        printf("IApp::registerForEvent\n");

        // ... 
    }
};

3 个答案:

答案 0 :(得分:8)

在IApp之后定义registerEvent。

class IApp;

class Component
{
    IApp* app;
    template<typename T>
    void registerEvent(const int& evtId, Status (T::*func) (int));
};


class IApp : public Component {
  ...
};

template <typename T>
Component::registerEvent(const int& evtId, Status (T::*func) (int)) {
  auto res = std::bind(func, (T*)this, std::placeholders::_1);
  app->registerForEvent(evtId);
}

如果需要,还可以在A::registerEvent之后定义Component::registerEvent

答案 1 :(得分:4)

你试图在它的基类中使用派生类,这对我来说似乎不是一个好的设计方法。我建议将它移到其他类可以访问的其他类中。

答案 2 :(得分:2)

您正在聚合派生类对象。因此,您可以通过奇怪的重复模板模式解决循环依赖性?

template <typename Aggregated>
class Component
{
    Aggregated* app;

    template<typename T>
    void registerEvent(const int& evtId, Status (T::*func) (int))
    {
        auto res = std::bind(func, (T*)this, std::placeholders::_1);
        app->registerForEvent(evtId);
    }
};

class IApp : public Component<IApp>
{
public:
    void registerForEvent(const int& evtId)
    {
        printf("IApp::registerForEvent\n");

        // ...
    }
};

尽管如此,我还不清楚你要做什么。对于一个你假设传递的函数Component :: registerEvent是Component的成员(你绑定到(T *)this)同时将事件ID委托给聚合的IApp。对我来说,似乎重新思考你的设计也可以解决循环依赖问题?