I have the following code fragment:
template <class T> struct ServicePtr { std::shared_ptr<T> service; ~ServicePtr() { std::cout << __PRETTY_FUNCTION__ << std::endl; } }; template <class T> struct ServicePtrDeleter { void operator()(ServicePtr<T>* ref) const { if (ref->service.get()) { if (IRunnable<T>* r=dynamic_cast<IRunnable<T>*>(ref->service.get())) { //std::cout << "Mark Thread Finished" << std::endl; r->stop(); } else { std::cout << __FILE__ << ":" << __LINE__ << std::endl; } } delete ref; } }; template <typename T> struct ServiceCreator { static std::shared_ptr< ServicePtr<T> > create() { std::shared_ptr< ServicePtr<T> > servicePtr(new ServicePtr<T>, ServicePtrDeleter< ServicePtr<T> >()); servicePtr->service.reset(new T); if (IRunnable<T>* r=dynamic_cast<IRunnable<T>*>(servicePtr->service.get())) { r->setSelfPtr(std::dynamic_pointer_cast<IRunnable<T>>(servicePtr->service)); } else { std::cout << __FILE__ << ":" << __LINE__ << std::endl; } return servicePtr; } }; ServiceCreator<T> , with T may or may not be derivated from IRunnable. I get the following compiler error(GCC 4.6.1):
In file included from /usr/lib/gcc/i686-pc-linux-gnu/4.6.1/../.. /../../include/c++/4.6.1/bits/shared_ptr.h:52:0, from /usr/lib/gcc/i686-pc-linux-gnu/4.6.1/../../../../include/c++/4.6.1/memory:86, from /usr/lib/gcc/i686-pc-linux-gnu/4.6.1/../../../../include/c++/4.6.1/thread:40, from main.cc:2: /usr/lib/gcc/i686-pc-linux-gnu/4.6.1/../../../../include/c++/4.6.1/bits/shared_ptr_base.h: In constructor 'std::__shared_count<_Lp>::__shared_count(_Ptr, _Deleter) [with _Ptr = ServicePtr<LogWriter>*, _Deleter = ServicePtrDeleter<ServicePtr<LogWriter> >, __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]': /usr/lib/gcc/i686-pc-linux-gnu/4.6.1/../../../../include/c++/4.6.1/bits/shared_ptr_base.h:771:37: instantiated from 'std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Tp1*, _Deleter) [with _Tp1 = ServicePtr<LogWriter>, _Deleter = ServicePtrDeleter<ServicePtr<LogWriter> >, _Tp = ServicePtr<LogWriter>, __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]' /usr/lib/gcc/i686-pc-linux-gnu/4.6.1/../../../../include/c++/4.6.1/bits/shared_ptr.h:128:37: instantiated from 'std::shared_ptr<_Tp>::shared_ptr(_Tp1*, _Deleter) [with _Tp1 = ServicePtr<LogWriter>, _Deleter = ServicePtrDeleter<ServicePtr<LogWriter> >, _Tp = ServicePtr<LogWriter>]' ServiceCreator.h:45:102: instantiated from 'static std::shared_ptr<ServicePtr<U> > ServiceCreator<T>::create() [with T = LogWriter]' main.cc:114:27: instantiated from here /usr/lib/gcc/i686-pc-linux-gnu/4.6.1/../../../../include/c++/4.6.1/bits/shared_ptr_base.h:480:8: error: no match for call to '(ServicePtrDeleter<ServicePtr<LogWriter> >) (ServicePtr<LogWriter>*&)' ServiceCreator.h:19:8: note: candidate is: ServiceCreator.h:21:7: note: void ServicePtrDeleter<T>::operator()(ServicePtr<T>*) const [with T = ServicePtr<LogWriter>] ServiceCreator.h:21:7: note: no known conversion for argument 1 from 'ServicePtr<LogWriter>*' to 'ServicePtr<ServicePtr<LogWriter> >*' Why ServicePtrDeleter::operator() gets instantiated with ServicePtr< ServicePtr<T> >? I just want to get T, inside operator(), so I can test whether it implements IRunnable or not.
main.cc:114 is auto logWriter=LogWriter::create(); It is a global variable.
class LogWriter: public ServiceCreator<LogWriter>, public IRunnable<LogWriter>, { .... }
shared_ptrinside ashared_ptr... ?