2015-01-09 18 views
8

Jak uzyskać arytmetyczną dowolną funkcję użytą jako parametr szablonu?Pobierz funkcję z parametru szablonu

Funkcja może być normalną funkcją, lambdą lub funktorem. Przykład:

template<typename TFunc> 
std::size_t getArity() 
{ 
    // ...? 
} 

template<typename TFunc> 
void printArity(TFunc mFunc) 
{ 
    std::cout << "arity: " << getArity<TFunc>() << std::endl; 
} 

void testFunc(int) { } 

int main() 
{ 
    printArity([](){}); // prints 0 
    printArity([&](int x, float y){}); // prints 2 
    printArity(testFunc); // prints 1 
} 

Mam dostęp do wszystkich funkcji C++ 14.

Czy muszę utworzyć specjalizację dla każdego typu funkcji (i wszystkich odpowiednich kwalifikatorów)? A może jest łatwiejszy sposób?

+2

Jaka jest twoja definicja arii variadic generic lambda? Lub funktora z wieloma przeciążonymi 'operator()' s biorąc różne liczby parametrów? –

+0

możliwy duplikat [Czy można określić typ parametru i typ zwracanej wartości lambda?] (Http://stackoverflow.com/questions/7943525/jest-jest-przypuszczony-do -figure-out-the-parametru -type-and-return-type-of-a-lambda) – Barry

+1

Potrzebne są tylko dwa przeciążenia: jeden dla wskaźników funkcji (łatwy, po prostu użyj 'sizeof ...' na dedukowanym pakiecie argumentów) i jeden dla lambd i innych klas (weź 'decltype' swojego' operator() ', a następnie wykonaj to samo). Jeśli 'operator()' jest przeciążony, nie masz szczęścia. – Brian

Odpowiedz

7

Zakładając, że wszystkie „s oraz funkcje mówimy o operator() nie są szablony lub przeciążony:

template <typename T> 
struct get_arity : get_arity<decltype(&T::operator())> {}; 
template <typename R, typename... Args> 
struct get_arity<R(*)(Args...)> : std::integral_constant<unsigned, sizeof...(Args)> {}; 
// Possibly add specialization for variadic functions 
// Member functions: 
template <typename R, typename C, typename... Args> 
struct get_arity<R(C::*)(Args...)> : 
    std::integral_constant<unsigned, sizeof...(Args)> {}; 
template <typename R, typename C, typename... Args> 
struct get_arity<R(C::*)(Args...) const> : 
    std::integral_constant<unsigned, sizeof...(Args)> {}; 

// Add all combinations of variadic/non-variadic, cv-qualifiers and ref-qualifiers 

Demo.

+1

Czy istnieje wersja podobna do Twojej, która obsługuje także ogólne lambdy? Http://coliru.stacked-crooked.com/a/1192b2686726d41d – James

Powiązane problemy