2012-12-19 12 views
5

Ok versagt, ich lese Throught recht einige Fragen „könnte nicht Template-Argument ableiten“, aber keiner scheint mein Fall zu passen - oder verstehe ich nicht die Antwort ...Ableiten Template-Argument für verschachtelte Vorlage

ist es one, dass ich Das Gefühl geht in die richtige Richtung, aber ich konnte die Lösung für mein Problem nicht finden.

Die abgespeckte Code in meinem Header sieht wie folgt aus:

template<typename T> 
class TemplateProblem 
{ 
public: 
    // Do I really need this or did I miss something from the STL? 
    template<typename Tin, typename Tout> 
    struct UnaryFunction : public std::unary_function<Tin, Tout> 
    { 
     virtual Tout operator()(Tin input) = 0; 
    }; 

    template<typename Tin, typename Tout> 
    struct StaticCast : public UnaryFunction<Tin, Tout> 
    { 
     virtual Tout operator()(Tin input) 
     { 
      return static_cast<Tout>(input); 
     } 
    }; 

private: 
    T * const _data; 
    T const _bias; 

    template<typename Tin> 
    void Init(Tin * data, int length, UnaryFunction<Tin, T> mapper, Tin bias); 

public: 
    template<typename Tin> 
    TemplateProblem(Tin * data, int length, Tin bias = Tin()); 

    template<typename Tin> 
    TemplateProblem(Tin * data, int length, UnaryFunction<Tin, T> mapper, Tin bias = T()); 
}; 

template<typename T> 
template<typename Tin> 
void TemplateProblem<T>::Init(Tin * data, int length, UnaryFunction<Tin, T> mapper, Tin bias) 
{ 
    T mappedBias = mapper(bias); 
    for (int i = 0; i < length; i++) 
    { 
     _data[i] = data[i] + mappedBias; 
    } 
} 

template<typename T> 
template<typename Tin> 
TemplateProblem<T>::TemplateProblem(Tin * data, int length, UnaryFunction<Tin, T> mapper, Tin bias = T()) 
    : _data(new T[length]), _bias(bias) 
{ 
    Init(data, length, mapper, bias); 
} 

template<typename T> 
template<typename Tin> 
TemplateProblem<T>::TemplateProblem(Tin * data, int length, Tin bias = T()) 
    : _data(new T[length]), _bias(bias) 
{ 
    StaticCast<Tin, T> cast; 
    Init(data, length, cast, bias); 
} 

ich es wie folgt instanziiert:

unsigned char pixels[] = {23, 42, 65, 97}; 
TemplateProblem<int> tp(pixels, 4); 

Von VS2012 ich diese Nachrichten erhalten:

Error 1 error C2784: 'void TemplateProblem<T>::Init(Tin *,int,TemplateProblem<T>::UnaryFunction<Tin,T>,Tin)' : could not deduce template argument for 'TemplateProblem<T>::UnaryFunction<Tin,T>' from 'TemplateProblem<T>::StaticCast<Tin,Tout>' ...\templateproblem.h 62 1 TemplateProblem 
Error 2 error C2893: Failed to specialize function template 'void TemplateProblem<T>::Init(Tin *,int,TemplateProblem<T>::UnaryFunction<Tin,T>,Tin)' ...\templateproblem.h 62 1 TemplateProblem 

Die Fehler tritt auch auf, wenn ich die beiden struct s aus class alsverschiebeschlägt vor.

+1

Der Instanziierungscode und die Fehlermeldungen sind völlig unabhängig voneinander. Der Fehler spricht über 'StaticCast ', aber Sie haben das nirgendwo in Ihrem Instanziierungscode. – Xeo

+0

http://liveworkspace.org/code/4psoUf$0 kompiliert gut ... Ihr Code (vor Korrekturen) konnte nicht kompiliert werden. – ForEveR

+0

@Xeo: StaticCast wird 3 Zeilen von unten verwendet. – primfaktor

Antwort

4

Der Compiler-Fehler ist nicht sehr hilfreich, um das tatsächliche Problem anzuzeigen.

Das eigentliche Problem ist, dass Sie UnaryFunction<Tin, T> durch den Wert Ihrer Init Funktion (und einer der Konstrukteure), aber alle Instanziierungen UnaryFunction<> Ergebnis in einer abstrakten Klasse übergeben (die nicht von Wert übergeben werden). Die einfache Lösung besteht darin, für UnaryFunction by-reference Pass zu verwenden, so dass mapper dem eigentlichen Objekt in bestanden bezeichnet

Die typische Lösung in der STL für functors vorbei ist, eine separate Vorlage Argument zu verwenden, wie diese.:

template<typename T> 
template<typename Tin, Tmapper> 
void TemplateProblem<T>::Init(Tin * data, int length, Tmapper mapper, Tin bias) 
{ 
    T mappedBias = mapper(bias); 
    for (int i = 0; i < length; i++) 
    { 
     _data[i] = data[i] + mappedBias; 
    } 
} 

Dann brauchen Sie nicht die UnaryFunctionL<> Basisklasse. Wenn eine inkompatible mapper übergeben wird, wird dies diagnostiziert, wenn es im Rumpf der Funktion verwendet wird.

+0

Das 'Tmapper' Template-Argument funktioniert * und * erleichtert das Leben. Danke vielmals! – primfaktor

Verwandte Themen