2010-03-01 17 views
8

Chciałbym utworzyć interfejs szablonów dla klas obsługi danych w moich projektach.Przesyłanie podpisu metody jako parametru szablonu do klasy

mogę napisać coś takiego:

template <class T> 
class DataHandler 
{ 
    public: 
     void Process(const& T) = 0; 
}; 

Następnie, załóżmy, że zdefiniowanie klasy w ten sposób:

class MyClass: public DataHandler<int> 
{ 
    void Process(const int&) { /* Bla-bla */ } 
} 

Teraz przyjść na pytanie, czy mogę jakoś określić mój interfejs szablon w sposób, w jaki jako parametr otrzyma nie tylko typ T, ale cały podpis funkcji Process().

chciałbym coś działa w ten sposób:

class MyClass: public DataHandler<void (int&)> 
{ 
    void Process(const int&) { /* Bla-bla */ } 
} 

jest to możliwe? Wiem, że na przykład boost :: signal odbiera parametry szablonu w ten sposób, ale jeśli dobrze rozumiem, używają tam dużo czarnej magii.

Odpowiedz

12

Tak, możesz. Ale w C++ 03, jesteś zobowiązany do kopiowania/wklejania kodu dla każdej liczby parametrów (niezbyt dobrze, ponieważ tutaj nie będziesz potrzebował przeciążenia dla const/non const itd. Constnes jest już znany!).

template<typename FnType> 
struct parm; 

template<typename R, typename P1> 
struct parm<R(P1)> { 
    typedef R ret_type; 
    typedef P1 parm1_type; 
}; 

template <class T> 
class DataHandler 
{ 
    typedef typename parm<T>::ret_type ret_type; 
    typedef typename parm<T>::parm1_type parm1_type; 

    public: 
     virtual ret_type Process(parm1_type t) = 0; 
}; 

class MyClass: public DataHandler<void (const int&)> 
{ 
    void Process(const int&) { /* Bla-bla */ } 
}; 

w C++ 0x, będzie można napisać

template <class T> 
class DataHandler; 

template<typename R, typename ... P> 
class DataHandler<R(P...)> 
{ 
    public: 
     virtual R Process(P... t) = 0; 
}; 

class MyClass: public DataHandler<void (const int&)> 
{ 
    void Process(const int&) { /* Bla-bla */ } 
}; 

Ile ładniejszy!

+0

Teraz pozostaje pytanie: ile lat zajmie, zanim będziemy mogli umieścić szablony variadic do codziennego użytku w pracy. Wiedząc, o ile prostsze może to boleć ... –

+0

A jak powinienem to zmienić, aby obsługiwać więcej niż jeden parametr w funkcji Process() w interfejsie DataProducer? To znaczy, chciałbym wesprzeć coś takiego jak DataHandler Lev

+0

@Lev, podejrzewam, że będziesz musiał częściowo wyspecjalizować 'DataHandler' na typie funkcji, aby uzyskać deklarację funkcji' Process' również. 'boost :: function' używa preprocesora do generowania potrzebnego kodu, ale w przypadku własnych projektów i kilku zastosowań, jest mało przydatne (moim zdaniem), aby przedstawić się w tym temacie, którego prawdopodobnie już nie potrzebujesz. Więc po prostu skopiuj/wklej 4 razy i gotowe :) –

Powiązane problemy