2015-07-21 127 views
8

在我的代碼中,我使用模板圖像類Image<T>std::shared_ptr的組合。這些圖像指針應該被傳遞給各種圖像處理功能,其中一些獨立於圖像類型。考慮Image<T>的以下定義,以及兩個處理函數function1()function2()相關類型:模板參數扣除失敗

#include <memory> 

template <typename T> 
struct Image 
{ 
    typedef std::shared_ptr<Image<T>> Ptr; 
}; 

template <typename T> 
void function1 (typename Image<T>::Ptr image) {} 

template <typename T> 
void function2 (std::shared_ptr<Image<T>> image) {} 

雖然function1()function2()有效地具有相同的簽名,function1()更容易閱讀和隱藏的指針是如何實現的細節。但是,我無法在不明確指定模板類型的情況下調用function1()。請看下面的代碼:

int main (void) 
{ 
    Image<int>::Ptr image = std::make_shared<Image<int>>(); 
    function1(image);  // Does NOT compile 
    function1<int>(image); // Does compile 
    function2(image);  // Does compile 
    return 0; 
} 

當第一次調用導致編譯錯誤:

example.cc: In function 'int main()': 
example.cc:18:19: error: no matching function for call to 'function1(MyClass<int>::Ptr&)' 
example.cc:18:19: note: candidate is: 
example.cc:10:6: note: template<class T> void function1(typename MyClass<T>::Ptr) 
example.cc:10:6: note: template argument deduction/substitution failed: 
example.cc:18:19: note: couldn't deduce template parameter 'T' 

我的問題是:是否有可能使用的function1()簽名,而無需手動指定模板參數?什麼導致編譯器錯誤?

我懷疑問題是由於Image<T>::Ptr是一個依賴類型。因此編譯器在編譯時無法知道該字段的確切定義。是否有可能告訴編譯器這個字段沒有專門化,typename關鍵字的精神告訴編譯器一個字段是一個類型?

回答

7

What is causing the compiler error?

使用非推斷上下文 T

你(只):嵌套名稱 - 符秒。也就是說,你把T放在一個名字裏面,這個名字只是指明類型在哪裏。編譯器無法理解你的實際意圖,並且不得不嘗試很多T's。

Is it possible to use the signature of function1() without having to manually specify the template argument?

不是。如果你想指的是智能指針到圖像的更簡潔的方式,你雖然可以使用別名模板:

template <typename T> 
using ImagePtr = std::shared_ptr<Image<T>>; 

而寫function1正是如此:

template <typename U> 
void function1(ImagePtr<U> p) {} 
+0

通過「不是真的」,你意思是「不」對吧? – Barry

+0

@Barry那麼,我還沒有檢查過,如果VC++中的瘋狂錯誤使它在那裏工作,但是 - 沒有。 – Columbo