2014-07-25 11 views
7

Mam pytanie dotyczące funkcjonalnych argumentów szablonu do klas szablonów w C++.Rozpakowywanie argumentów parametru funkcjonalnego do klasy szablonu C++

chciałbym zdefiniować klasę szablonu Foo biorąc jeden parametr szablonu Fun

template <typename Fun> 
    struct Foo { 
     ... 
    }; 

taki sposób, że dana funkcja jak

void bar(std::string a, float b, char c) 
    { 
     ... 
    } 

następnie Foo<bar>::args_t będzie równoznaczne z typedef dla

std::tuple<std::string, float, char> 

Czy to p kostny? (Użycie std::tuple jest tutaj tylko dla konkretności, bardziej ogólnie zastanawiam się, czy można zrobić coś takiego jak dopasowywanie wzorca na argumentach funkcjonalnego parametru szablonu.)

Chodzi o to, aby uniknąć konieczności definiowania Foo w taki sposób, jak

template Foo<typename A, typename B, typename C, typename D, 
     D (*Fun)(A a, B b, C c)> 
    struct Foo { 
     typedef std::tuple<A,B,C> args_t; 
    }; 

która wymaga zarówno podjęciem stałej liczbie argumentów funkcji i wymagający argument i powrotu rodzaje funkcji, które należy dostarczyć jawnie jako parametry szablonu. (Definiowanie Foo przy użyciu szablonów variadic może prawdopodobnie rozwiązać poprzedni problem, ale co z tym ostatnim?)

Dzięki!

+0

Look w zmiennej liczbie argumentów szablonów. Również możesz chcieć unikać typów nazw za pomocą '_t', ponieważ są one zarezerwowane w POSIX. – user657267

+1

@ user657267 Jestem dość świadomy szablonów variadic i wspomniałem je w moim pytaniu. Komentarz na temat typów nazw za pomocą wyrażenia "_t" wydaje się być nieco poza lewym polem. – factotum

+0

Dlatego jest to komentarz, a nie odpowiedź. – user657267

Odpowiedz

11

Zadeklaruj szablon podstawowy i pozostaw go niezatwierdzony.

template<typename T> 
struct foo;  // unimplemented primary template 

Następnie należy podać częściową specjalizację, która dopasowuje typy funkcji do argumentu szablonu.

template<typename Result, typename... Args> 
struct foo<Result(Args...)> 
{ 
    using args_t = std::tuple<Args...>; 
}; 

Możesz uzyskać dostęp do typu zagnieżdżonego jak

foo<decltype(bar)>::args_t 

Live demo

+0

Świetne, 'decltype' wydaje się być kluczem, dzięki bardzo! – factotum

Powiązane problemy