2

我有一个带有方法模板的类:

struct Subject
{
  template <typename T>
  void doSomething()
  {
    ..
  }
};

现在,无论何时doSomething(使用 any T),我都希望通知“观察者”:

  template <typename T>
  void onDoSomething()
  {
    ..
  }

观察者是一个方法模板很重要(包含方法的类模板也可以工作)。如果不是,我可以实现通用观察者模式。

可以修改Subject::doSomething(),以便它调用一个方法。但是,该类Subject不应该“知道”具体的观察者/观察者方法。

这背后的想法是:我Subject在两个项目中使用。我只需要(并且拥有)其中一个观察者。

有什么办法可以做到这一点?

4

2 回答 2

2

艰难的一个。它似乎归结为

通知必须在编译时可解析(它是一个模板)

同时,

通知在编译时不应该是可解析的(Subject不应该知道观察者)

我可以想到两种方法来做到这一点:


1.添加一个重载doSomething

template <typename T, typename Observer>
void doSomething()
{
  doSomething<T>();
  Observer::onDoSomething<T>();
}

然后在项目A中调用单参数版本,在项目B中调用双参数版本。


2.让定义的文件Subject包含一个标题,该标题将在每个项目中进行不同/不同的配置:

主题.h

#include "observer_def.hpp"

struct Subject
{
  template <typename T>
  void doSomething()
  {
    ..
    notifyDoSomething<T>();
  }
};

项目 A 中的observer_def.hpp

template <typename>
inline void notifyDoSomething() {}

项目 B 中的 observer_def.hpp

template <typename T>
inline void notifyDoSomething()
{
  MyObserver::onDoSomething<T>();
}
于 2013-04-04T10:24:51.980 回答
1

我终于通过模板专业化找到了一个令人满意的解决方案:

///signaling struct. Could be replaced with any other type.
struct SpecializedObserver{};

///unspecialized:
template <typename>
struct Observer
{
    template <typename T>
    static void onDoSomething()
    {
        //default: do nothing.
    }
};

///optional. Specialize in project A or leave aside in project B:
template<>
struct Observer<SpecializedObserver>
{
    template <typename T>
    static void onDoSomething()
    {
        std::cout << "doing something with " << typeid(T).name() << std::endl; 
    }
};

struct Subject
{
    template <typename T>
    void doSomething()
    {
      Observer<SpecializedObserver>::onDoSomething<T>();
      ..
    }
};

如果我不想要观察者,此解决方案不需要任何操作。如果我想要一个,我会专门使用 Observer 模板,如上所示。

编辑:这在我的测试中运行良好,但是问题是我如何在具有不同编译单元的场景中使用它——我应该在哪里定义专业化?

于 2013-04-04T11:06:37.160 回答