我在我的库中使用主题观察者模式的奇怪重复模板模式取得了很好的成功。我使用 gcc 和 Visual Studio 2017 进行编译。这段代码已经在 Windows 和 Linux 机器上使用了几个月。
最近,我决定重构。将 CRTP Subject Observer 移至最小模板,然后将 CUDA 特定部分移至派生类。像这样:
SubjectObserver.hpp:
#ifndef SUBJECTOBSERVER_HPP_
#define SUBJECTOBSERVER_HPP_
template <typename T_subject, typename T_message> class Observer
{
public:
virtual void ReceiveMessage( T_subject* subject, T_message message ) = 0;
protected:
T_subject & subject;
Observer( T_subject & subject )
:
subject( subject ){ subject.RegisterObserver( *this ); }
~Observer(){ subject.UnregisterObserver( *this ); }
};
#endif /* SUBJECTOBSERVER_HPP_ */
和 CudaSubjectObserver.hpp:
#ifndef CUDASUBJECTOBSERVER_HPP_
#define CUDASUBJECTOBSERVER_HPP_
#include "SubjectObserver.hpp"
template <typename T_subject, typename T_message> class CudaObserver : public Observer<T_subject, T_message>{
public:
void ReceiveMessageBase( T_subject* subject, T_message message, cudaEvent_t message_ready ){
/*.....*/
ReceiveMessage( subject, message );
/*.....*/
}
protected:
CudaObserver( T_subject & subject, cudaStream_t & observer_stream )
:
Observer<T_subject, T_message>( subject ),
{ }
~CudaObserver(){ }
};
#endif /* CUDASUBJECTOBSERVER_HPP_ */
使用 Visual Studio 2017,可以很好地构建。使用 gcc 5.4.0,我在 CudaObserver 中获得了对 Observer 成员变量和方法的“未定义引用”。喜欢:
../CudaSubjectObserver.hpp:78:17: error: ‘ReceiveMessage’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
通过在 CudaObserver 中明确指定可以很容易地修复它:
Observer<T_subject, T_message>::ReceiveMessage( subject, message );
但我想更好地了解造成这种情况的原因。显然,如果我通过 -fpermissive 标志,隐式形式会建立吗?这是不好的做法吗?因为我确实欣赏较短的隐式形式。它更容易阅读。