Я добился большого успеха, используя шаблон любопытных повторяющихся шаблонов для шаблона Subject Observer в моей библиотеке. Я компилирую с помощью gcc и Visual Studio 2017. Этот код месяцами использовался на компьютерах с Windows и Linux.
Недавно я решил провести рефакторинг. Перемещение предметного наблюдателя CRTP в минимальный шаблон, затем специфичные для 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, то неявная форма будет создана? Это плохая практика? Потому что я ценю более короткую неявную форму. Это легче читать.