Количество аргументов функции

239
22 декабря 2017, 02:13

Недавно был вопрос о том, как объявить функцию с n аргументами заданного типа. У меня возник противоположный вопрос. Как узнать количество аргументов функции?

#include <iostream>
void foo(float, int){
}
int main(){
    std::cout << doTemplateMagic(foo); //2
}
Answer 1

Boost.TypeTraits, например

#include <type_traits>
#include <boost/type_traits.hpp>
void f(int, char) {}
int n = boost::function_traits<std::remove_pointer_t<decltype(&f)>>::arity;
Answer 2

Можно использовать темплейт с переменным числом параметров:

#include <iostream>
template <typename R, typename ... Types> constexpr size_t getArgumentCount( R(*f)(Types ...))
{
   return sizeof...(Types);
}
//----------------------------------    
// Test it out with a few functions.
//----------------------------------    
void foo(int a, int b, int c)
{
}
int bar()
{
   return 0;
}
int baz(double)
{
   return 0;
}
int main()
{
    std::cout << getArgumentCount(foo) << std::endl;
    std::cout << getArgumentCount(bar) << std::endl;
    std::cout << getArgumentCount(baz) << std::endl;
    return 0;
}

Вывод:

3
0
1

Или использовать этот метод:

template <typename R, typename ... Types> 
constexpr std::integral_constant<unsigned, sizeof ...(Types)> getArgumentCount( R(*f)(Types ...))
{
   return std::integral_constant<unsigned, sizeof ...(Types)>{};
}
// Guaranteed to be evaluated at compile time
size_t count = decltype(getArgumentCount(foo))::value;

или

// Most likely evaluated at compile time
size_t count = getArgumentCount(foo).value;

Источник: https://stackoverflow.com/questions/36797770/get-function-parameters-count

Answer 3

Немного покритикую остальные ответы, приводя цитату:

“Don't try to write helper code to detect PMFs/PMDs and dispatch on them -- it is an absolute nightmare. PMF types are the worst types by far in the core language.”

Используйте Boost.CallableTraits

#include <type_traits>
#include <boost/callable_traits.hpp>
namespace ct = boost::callable_traits;
int main() {
    auto lamda = [](int, float&, const char*){};
    using lam = decltype(lamda);
    static_assert(std::tuple_size_v<ct::args_t<lam>> == 3);
}
READ ALSO
Реализация поиска простых делителей

Реализация поиска простых делителей

Всем привет, написал код по поиску простых чисел и запоминания этих чисел и их степеней:

288
Сканер отпечатков пальцев в Qt для iOS и Android

Сканер отпечатков пальцев в Qt для iOS и Android

Нужно немного поработать со встроенными в смартфоны сканерами отпечатков пальцев на iOS и AndroidC++/Qt/qml

234
Сортировка строки двумерного массива

Сортировка строки двумерного массива

Задача: Написать функцию которая принимает указатель на двумерный массив , количество строк, количество столбцов и строку k которую нужно...

257
Помогите разобраться с MinGW C++

Помогите разобраться с MinGW C++

Работаю в CodeBlocksПодключено несколько библиотек

209