2016-05-03 10 views
1

In diesem Beispiel erstelle ich eine Functor-Klasse, die Funktionen als Parameter übernimmt. Der zweite Funktor soll ein Objekt des ersten Funktors als Template-Parameter nehmen und eine Funktion des ersten Funktors aufrufen. Ich bin mir nicht sicher, wie die Vorlage für den zweiten Functor aussehen muss.Template-Klasse als Template-Klassenparameter

Dies ist die erste Functor, die wie erwartet funktioniert:

typedef float (*pDistanceFu) (float, float); 
typedef float (*pDecayFu) (float, float, float); 

template <pDistanceFu Dist, pDecayFu Rad, pDecayFu LRate> 
class DistFunction {  
public: 
    DistFunction() {} 
    DistFunction(char *cstr) : name(cstr) {}; 

    char *name; 
    float distance(float a, float b) { return Dist(a,b); }; 
    float rad_decay(float a, float b, float c) { return Rad(a,b,c); }; 
    float lrate_decay(float a, float b, float c) { return LRate(a,b,c); }; 
}; 

Hier erstelle ich eine Instanz der Funktor, die spezialisiert ist:

DistFunction<foo,bar,foobar> fcn_gaussian((char*)"gaussian"); 

Hier kann ich nicht wissen, wie die Vorlage hat zu suchen, zu nehmen jede Art von DistFunction < ...> als Parameter

template<template<DistFunction> typename = F> 
struct functor { 
    float fCycle; 
    float fCycles; 

    functor(float cycle, float cycles) : fCycle(cycle), fCycles(cycles) {} 

    float operator()(float lrate) { 
    return (F.lrate_decay)(lrate, fCycle, fCycles); 
    } 
}; 

Wie ich den zweiten Funktors verwenden möchten:

typedef DistFunction<foo,bar,foobar> gaussian; 
void test() { 
    functor<gaussian> test(0,1); 
} 

Die Fehler:

error: argument list for class template "DistFunction" is missing 
error: expected "class" 
error: expected a "," or ">" 
+0

Wie verwenden Sie 'funktor'? 'Funktor '? – songyuanyao

+0

Aktualisiert die Frage, wahrscheinlich nicht möglich, dass der Compiler die Vorlage Informationen aus dem Objekt bekommt .., ich denke, – dgrat

+0

Wer bietet das Funktor-Objekt? –

Antwort

2

Dies ist eine unbenannte Vorlage Template-Parameter mit einem si ngle Nicht-Typ-Parameter vom Typ DistFunction und Standardwert F. Da DistFunction kein Typ ist (es ist eine Klassenvorlage) und F nicht existiert, macht das keinen Sinn.

Sie benötigen hier keine Vorlagenparameter. Die einfache

template<typename F> 
struct functor { 

sollte die Aufgabe erledigen.

Wenn Sie F beschränken wollen, das heißt, nur erlauben es verschiedene Ausprägungen von DistFunction und nichts anderes zu akzeptieren, müssen Sie verschiedene Sprach Einrichtungen wie static_assert und/oder enable_if. Dies wird nur für bessere Fehlermeldungen benötigt, falls jemand functor falsch instanziiert. Verwenden Sie einfach F, als wäre es ein DistFunction.

+0

Sie hatten Recht. Mein Fehler war, dass ich den Konstruktor vergessen habe. Die Mitglieder statisch zu machen, hat sogar meinen Testcode funktionieren lassen. Ich bin so dumm. – dgrat

2

Versuchen

template<typename F> 
struct functor { 
    float fCycle; 
    float fCycles; 

    functor(float cycle, float cycles) : fCycle(cycle), fCycles(cycles) {} 

    float operator()(float lrate) { 
    return F((char*)"gaussian").lrate_decay(lrate, fCycle, fCycles); 
    } 
}; 

LIVE

+0

Dies schlägt fehl, weil lrate_decay unbekannt ist. Außerdem möchte ich die Laufzeit-Erstellung von DistFunction vermeiden. – dgrat

+0

@dgrat Dann müssen Sie es jedes Mal erstellen, wenn Sie 'operator()' '' funktor 'aufrufen. – songyuanyao

+0

Dies bringt nichts, Sie rufen nicht 'test.operator()'. –

Verwandte Themen