2015-07-21 10 views
8

In meinem Code verwende ich eine Vorlagenklasse Image<T> in Kombination mit std::shared_ptr. Diese Bildzeiger sollen an verschiedene Bildverarbeitungsfunktionen übergeben werden, von denen einige unabhängig vom Bildtyp sind. Betrachten Sie die folgende Definition von Image<T> und zwei Verarbeitungsfunktionen function1() und function2().Abhängige Typen: Vorlage Argumentabzug fehlgeschlagen

#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) {} 

Während function1() und function2() effektiv die gleiche Signatur haben, ist function1() leichter zu lesen und verbirgt die Details, wie der Zeiger realisiert wird. Ich habe jedoch Probleme, function1() aufzurufen, ohne den Vorlagentyp explizit anzugeben. Betrachten Sie den folgenden Code ein:

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; 
} 

Wo der erste Aufruf der Compiler-Fehler führt:

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' 

Meine Frage ist folgende: Ist es möglich, die Unterschrift von function1() zu verwenden, ohne manuell angeben, die Vorlagenargument? Was verursacht den Compilerfehler?

Ich vermute, dass das Problem durch die Tatsache verursacht wird, dass Image<T>::Ptr ein abhängiger Typ ist. Daher kann der Compiler die genaue Definition dieses Felds zur Kompilierungszeit nicht kennen. Ist es möglich, dem Compiler mitzuteilen, dass es keine Spezialisierungen dieses Feldes im Sinne des Schlüsselwortes typename geben wird, das dem Compiler sagt, dass ein Feld ein Typ ist?

Antwort

7

What is causing the compiler error?

Sie sind (nur) mit T in einem nicht abgeleiteten Kontext: verschachtelte-name-specifier s. Das heißt, Sie setzen T in einen Namen, der lediglich angibt, wo der Typ liegt. Der Compiler kann Ihre tatsächliche Absicht nicht verstehen und müsste eine Menge von T versuchen.

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

Nicht wirklich. Wenn Sie eine prägnante Art und Weise der Bezugnahme auf einen Smart-Zeiger auf ein Bild möchten, können Sie eine Alias-Vorlage obwohl verwenden:

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

Und schreiben function1 thusly:

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

Mit „nicht wirklich“, Sie mein nein, oder? – Barry

+0

@Barry Nun, ich habe nicht überprüft, ob ein wahnsinniger Fehler in VC++ es funktioniert, aber ja - nein. – Columbo