2012-01-30 8 views
23

ten jest kontynuacją tego problemu: Generic functor for functions with any argument listJak uzyskać typy argumentów dla wskaźnika funkcji w klasie szablonu variadic?

mam tej klasy funktora (pełny kod patrz link powyżej):

template<typename... ARGS> 
class Foo 
{ 
    std::function<void(ARGS...)> m_f; 
    public: 
    Foo(std::function<void(ARGS...)> f) : m_f(f) {} 
    void operator()(ARGS... args) const { m_f(args...); } 
}; 

W operatora() można uzyskać dostęp z łatwością args ... funkcja rekursywnego "obierania" opisana tutaj http://www2.research.att.com/~bs/C++0xFAQ.html#variadic-templates

Mój problem: chcę uzyskać dostęp do typów argumentów f, tj. ARGS ..., w konstruktorze. Oczywiście nie mogę uzyskać dostępu do wartości, ponieważ do tej pory ich nie ma, ale lista typów argumentów jest w jakiś sposób pochowana w f, nieprawdaż?

Odpowiedz

48

Możesz napisać function_traits klasę, jak pokazano poniżej, aby odkryć typy argumentów, rodzaj powrotu, a liczbę argumentów:

template<typename T> 
struct function_traits; 

template<typename R, typename ...Args> 
struct function_traits<std::function<R(Args...)>> 
{ 
    static const size_t nargs = sizeof...(Args); 

    typedef R result_type; 

    template <size_t i> 
    struct arg 
    { 
     typedef typename std::tuple_element<i, std::tuple<Args...>>::type type; 
    }; 
}; 

kod Test:

struct R{}; 
struct A{}; 
struct B{}; 

int main() 
{ 
    typedef std::function<R(A,B)> fun; 

    std::cout << std::is_same<R, function_traits<fun>::result_type>::value << std::endl; 
    std::cout << std::is_same<A, function_traits<fun>::arg<0>::type>::value << std::endl; 
    std::cout << std::is_same<B, function_traits<fun>::arg<1>::type>::value << std::endl; 
} 

Demo: http://ideone.com/YeN29

+0

Dziękujemy @Nawaz, działa do tej pory. Niemniej jednak, chciałbym wydobyć "magię" z tego rozwiązania i umieścić ją w moim kodzie. Przypuszczam, że nazwa_testu std :: tuple_element > :: type to miejsce, w którym to się dzieje ... Jak to zrobić, bez konieczności deklarowania kolejnej struktury – steffen

+0

@steffen: Czy masz jakiś problem przy definiowaniu innej struktury które można wykorzystać również w innych sytuacjach? Również umieszczenie całego kodu w jednej klasie nie jest dobrym pomysłem. Spróbuj podzielić kod na małe jednostki robocze. – Nawaz

+0

Dostaję twój punkt. Ostatnie pytanie to ten fragment kodu z biblioteki boost? function_traits brzmi znajomo;) – steffen

Powiązane problemy