2011-12-27 20 views
8

Obecnie używam tego kodu: (. Użytkownik nie może zadzwonić argc z funkcji z dowolnej liczby argumentów)Pierwsze count argument wskaźnik funkcji

size_t argc(std::function<Foo()>) 
    { return 0; } 

    size_t argc(std::function<Foo(Bar)>) 
    { return 1; } 

    size_t argc(std::function<Foo(Bar, Bar)>) 
    { return 2; } 

    size_t argc(std::function<Foo(Bar, Bar, Bar)>) 
    { return 3; } 

    // ... 

Ale to jest trochę brzydki i ograniczone Czy istnieje lepszy sposób na zrobienie tego?

Uwaga: typ powrotu i typ argumentu są zawsze takie same. Wiem, że mogę używać szablonów do akceptowania dowolnego typu, ale nie potrzebuję tego.

+0

UMH typu argumentu nie zawsze jest taka sama ... –

+1

@ JohannesSchaub-litb myślę, to znaczy, że są zawsze takie same, jak w przykłady: 'Foo' dla wartości zwracanej i' Bar' dla wszystkich argumentów. –

Odpowiedz

12

Cleaner wersja @ odpowiedź Paola, nadające się do rzeczywistych obiektów:

template<class R, class... Args> 
constexpr unsigned arity(std::function<R(Args...)> const&){ 
    return sizeof...(Args); 
} 
5

Następujące będzie działać na każdym liczbę operandów, ale przyjąć dowolne rodzaje argumentów:

template <typename T> 
struct arity 
{ 
}; 

template <typename... Args> 
struct arity<std::function<Foo(Args...)>> 
{ 
    static const int value = sizeof...(Args); 
}; 

Jeśli naprawdę chcesz, aby ograniczyć swój typ argumentów za funkcje typu Foo(Bar, Bar, ...), można zrobić coś takiego:

template <typename T> 
struct arity 
{ 
}; 

template <typename... Args> 
struct const_tuple 
{ 
}; 

template <> 
struct const_tuple<> 
{ 
    struct unsupported_function_type { }; 
}; 

template <typename... Args> 
struct const_tuple<Bar, Args...> 
{ 
    typedef typename const_tuple<Args...>::unsupported_function_type unsupported_function_type; 
}; 

template <typename... Args> 
struct arity<std::function<Foo(Args...)>> : public const_tuple<Args...>::unsupported_function_type 
{ 
    static const int value = sizeof...(Args); 
}; 

To spowoduje błąd kompilacji, gdy wywoływane jest arity z nieobsługiwanym typem funkcji.