2013-08-01 6 views
7

Für das Leben von mir, ich kann nicht dieses einfache Stück arkane Magie Vorlage an der Arbeit:Template-Template-Funktionsparameter

template<typename T, int a, int b> 
int f(T v){ 
    return v*a-b; // just do something for example 
} 

template<typename T, int a, int b, template<typename,int,int> class func> 
class C{ 
    int f(){ 
    return func<T,a,b>(3); 
    } 
}; 

int main(){ 
    C<float,3,2, f> c; 
} 

dies möglich ist, ohne Beteiligung functors zu tun?

+0

Was genau versuchen Sie zu erreichen? – nijansen

+0

mein Compiler stürzte während der Ausführung dieses Codes ab. – Saksham

+0

@nijansen ist nicht MSVS2010 stabil ?? – Saksham

Antwort

7

f soll eine Klasse sein - Sie haben eine Funktion.

Siehe unten:

// Class acts like a function - also known as functor. 
template<typename T, int a, int b> 
class f 
{ 
    int operator()(T v) 
    { 
    return v*a-b; // just do something for example 
    } 
}; 

template<typename T, int a, int b, template<typename,int,int> class func> 
class C 
{ 
    int f() 
    { 
    return func<T,a,b>(3); 
    } 
}; 

int main() 
{ 
    C<float,3,2, f> c; 
} 

... Und die angepasste Version, wenn Sie benötigen Port Legacy-Code (Passt sich die Funktion einer Klasse-Vorlage):

#include <iostream> 


template<typename T, int a, int b> 
int f(T v) 
{ 
    std::cout << "Called" << std::endl; 
    return v*a-b; // just do something for example 
} 

template<typename T, int a, int b, template<typename,int,int> class func> 
struct C 
{ 
    int f() 
    { 
    return func<T,a,b>(3); 
    } 
}; 

template <class T, int a, int b> 
struct FuncAdapt 
{ 
    T x_; 
    template <class U> 
    FuncAdapt(U x) 
    : x_(x) 
    {} 
    operator int() const 
    { 
    return f<T,a,b>(x_); 
    } 
}; 

int main() 
{ 
    C<float,3,2, FuncAdapt > c; 
    c.f(); 
} 
+0

herzlichen glückwunsch für ihre ersten punkte – Saksham

+0

Danke. Ich sehe, ich brauche einen Ruf, um jemanden zu belohnen ... Daher habe ich eine Frage beantwortet. –

+0

Hatte das OP es nicht gewünscht, ohne Funktoren zu benutzen? (Zitat: "Ist das möglich, ohne Funktoren einzubeziehen?") –

-1

Nein, ist es nicht. Auch die Syntax:

template <typename T, int a, int b, template <typename, int, int> class func> 
                    ^^^^^ 

zeigt, dass ein Argument für einen Template-Template-Parameter eine Klassenvorlage sein muss.

+0

Ja ich weiß, ich suchte nach etwas Trickerei, nur um zu vermeiden, meinen Produktionscode zu ändern, um Unit-Test-Code sauberer zu machen. –

0

Der Grund Compiler ist beschwerlich ist, dass Sie eine Funktion (f) als Klasse an den letzten Template-Parameter für die Klasse C übergeben.

Da Sie eine Funktion nicht als Vorlageparameter übergeben können, sollten Sie Funktionszeiger oder Funktoren verwenden. Und Funktoren sind definitiv der sauberere Weg, dies zu tun.

Also, obwohl es möglich ist zu erreichen, was Sie wollen, ohne Funktoren zu verwenden, sollten Sie wirklich nicht versuchen.

Wenn Sie Funktionszeiger verwenden Sie etwas wie folgt aussehen wird:

template<typename T, int a, int b, int (*func)(T)> 
class C{ 
    int f(){ 
     return (*func)(3); 
    } 
}; 

int main(){ 
    C< float,3,2,&f<float,3,2> > c; 
} 

In diesem Fall ich glaube nicht, dass Sie den Code-Duplizierung in der Erklärung von c zu beseitigen wäre in der Lage, aber ich könnte falsch liegen.

6

Sie können es durch eine kleine Tricks lösen:

template<typename T, int a, int b> 
int f(T v){ 
    return v*a-b; // just do something for example 
} 

template<typename T, int, int> 
using func_t = int (*)(T); 

template<typename T, int a, int b, func_t<T, a, b> func> 
class C{ 
    int f(){ 
    return func(3); 
    } 
}; 

C<float,3,2, f<float, 3, 2>> c; 

Zuerst müssen Sie ein Typ-Alias ​​für die Funktion (func_t oben), und Sie müssen leider die Template-Argumente in der Erklärung von c duplizieren.

+1

... in C++ 11, wenn Ihr Compiler Template-Aliase unterstützt. MSVC 2013 * immer noch * nicht – SteveLove

+0

Ich wollte die Duplizierung der Template-Argumente vermeiden, das soll mich in meinen Unit-Tests vor der Typisierung/Copypaste retten. Davon abgesehen ist dies die beste Antwort bisher. –