2012-01-30 17 views
0

我有以下代碼片段:具體C++模板特

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>,其中T可以或可以不從IRunnable衍生化。 我得到以下編譯器錯誤(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> >*' 

爲什麼ServicePtrDeleter::operator()獲取與ServicePtr< ServicePtr<T> >實例?我只想得到T,在operator()之內,所以我可以測試它是否實現IRunnable或不。

main.cc:114是auto logWriter=LogWriter::create();它是一個全局變量。

class LogWriter: 
     public ServiceCreator<LogWriter>, 
     public IRunnable<LogWriter>, 
{ 
.... 
} 
+0

又有什麼問題? (編輯你的問題,並添加直接問題到它的結尾) – Vyktor 2012-01-30 12:13:43

+0

我現在正在解決這個問題。你們太快了。 – 2012-01-30 12:16:54

+0

在main.cc中,你如何使用這些類?你能向我們展示114行附近的代碼(錯誤發生的地方)嗎? – 2012-01-30 12:17:04

回答

3

ServicePtrDeleter在此實例:

std::shared_ptr< ServicePtr<T> > servicePtr(new ServicePtr<T>, ServicePtrDeleter< ServicePtr<T> >()); 

ServicePtrDeleter模板參數是ServicePtr<T>

當您用ServicePtr<T>代替的ServicePtrDeleter的模板參數時,最終得到的參數爲ServicePtr< ServicePtr<T> >

你可能只是想在實例使用T模板參數,因爲ServicePtrDeleter包裝了成ServicePtr本身:

... servicePtr(new ServicePtr<T>, ServicePtrDeleter<T>()); 
+0

OMG。是的,這解決了編譯錯誤,並在第一眼看到作品。在我接受這個答案之前,你能解釋一下,爲什麼opetator()(ServicePtr *)沒有專業化。據我瞭解C++類型系統它選擇最合適的匹配。當我將ServicePtr *傳遞給operator()時,C++是否應該明白這是匹配的並從中提取T?或者我只是錯誤: – 2012-01-30 12:44:17

+0

這是因爲你試圖專門化或實例化模板結構/類而不是模板函數......使用結構/類模板,除非專門創建單獨的專用結構/類與專門的模板參數。例如,'template <> struct ServiceCreator {...};'。另外,C++編譯器不能從返回類型中推導出模板參數,只能從函數的參數中推導出來,所以即使你創建了一個模板函數,你也必須指定模板參數。 – Jason 2012-01-30 12:47:50

+0

沒有涉及專業化。你只有一個類模板,當用某個類型'X'實例化時,它將有一個'void operator()(ServicePtr *)const'。無論X型是什麼類型。 – sth 2012-01-31 21:15:36