I've had good success using the Curiously Recurring Template Pattern for the Subject Observer pattern in my library. I compile with gcc and Visual Studio 2017. This code has been used for months on both Windows and Linux machines.
Recently, I decided to refactor. Moving the CRTP Subject Observer to a minimal template, then the CUDA-specific parts to a derived class. Like so:
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_ */
And 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_ */
With Visual Studio 2017, this builds fine. With gcc 5.4.0, I get "undefined references" in CudaObserver to Observer member variables and methods. Like:
../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]
Which can be fixed easily enough by explicitly specifying within CudaObserver:
Observer<T_subject, T_message>::ReceiveMessage( subject, message );
But I would like to understand better the cause for this. Apparently if I pass the -fpermissive flag the implicit form would build? Is this bad practice? Because I do appreciate the shorter implicit form. It's easier to read.