2013-08-01 19 views
7

Dla życia mnie, nie mogę dostać ten prosty kawałek magii tajemnej szablonu do pracy:szablon szablon funkcji parametr

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

Czy jest to możliwe do zrobienia bez angażowania funktory?

+0

Co dokładnie próbujesz osiągnąć? – nijansen

+0

Mój kompilator zawiesił się podczas wykonywania tego kodu. – Saksham

+0

@nijansen nie jest stabilny MSVS2010? – Saksham

Odpowiedz

7

f ma być klasą - masz funkcję.

Patrz poniżej:

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

... A wersja przystosowana jeśli trzeba kod portu starszych (Dostosowuje funkcji do szablonu klasy):

#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

Gratulacje za pierwsze punkty – Saksham

+0

Dzięki. Widzę, że potrzebuję reputacji, aby kogoś upomnieć ... Dlatego odpowiedziałem na pytanie. –

+0

Czy OP nie chciał tego bez użycia funktorów? (cytuję: "Czy można to zrobić bez udziału funktorów?") –

-1

Nie, nie jest. Nawet składnia:

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

pokazuje, że argument dla parametru szablonu szablonu musi być szablonem klasy.

+0

Tak, wiem, szukałem jakiegoś oszustwa, aby uniknąć zmiany kodu produkcyjnego, aby kod testowania jednostki był bardziej zgrabny. –

0

Powodem jest kompilator narzekasz, że przekazujesz funkcję (f) jako klasę do ostatniego parametru szablonu dla klasy C.

Ponieważ nie można przekazać funkcji jako parametru szablonu, należy użyć wskaźników funkcji lub funktorów. A funktory są zdecydowanie lepszym sposobem na zrobienie tego.

Tak więc, mimo że można osiągnąć to, czego chcesz, bez używania funktorów, naprawdę nie powinieneś próbować.

Jeśli chcesz użyć wskaźników funkcji będzie patrząc na coś takiego:

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

W takim razie ja nie sądzę, by być w stanie wyeliminować powielanie kodu w deklaracji c, ale mogę się mylić.

6

Można go rozwiązać za pomocą małego oszustwa:

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; 

Najpierw trzeba typu alias dla funkcji (func_t powyżej), i niestety trzeba powielać argumenty szablonu w deklaracji c.

+1

... w C++ 11, jeśli Twój kompilator obsługuje aliasy szablonów. MSVC 2013 * nadal * nie jest – SteveLove

+0

Chciałem uniknąć powielania argumentów szablonu, to ma na celu uratowanie mnie przed pisaniem/kopiowaniem dużo podczas testów jednostkowych. Appart z tego, jest to najlepsza odpowiedź do tej pory. –