Здравствуйте, c-smile, Вы писали:
CS>Есть такой полезный тип как std::function<signature>. CS>Стоит задача получения количества аргументов в сигнатуре функции и их типов. В compile time есс-но. CS>Почему-то в std::function я этого не нашел.
CS>...
Кстати, в бусте есть:
#include <stdio.h>
#include <boost/function_types/function_arity.hpp>
using namespace boost::function_types;
template< class CallableT >
size_t GetArity(CallableT fnc)
{
return function_arity< CallableT >::value;
}
int main(int argc, char * argv[])
{
printf("main:%u", GetArity(main));
}
Re: std::function<...> получение количества и типа параметров
Здравствуйте, PM, Вы писали:
PM>Здравствуйте, jazzer, Вы писали:
CS>>>Стоит задача получения количества аргументов в сигнатуре функции и их типов. В compile time есс-но.
J>>это часть бустовских type_traits (т.е. в какой-то момент должна появиться и в std) J>>http://www.boost.org/doc/libs/1_55_0/libs/type_traits/doc/html/boost_typetraits/reference/function_traits.html
PM>Интересно, почему типы аргументов фнукции сделали через typedef see-below argN_type; вместо хранения всех типов аргументов в tuple или mpl::vector. Как в таком случае использовать n-ый аргумент в runtime? Допустим, у меня есть
Предполагаю, чтобы уменьшить зависимости. type_traits — это очень базовая библиотека, не зависящая почти ни от чего (с прицелом на включение в стандарт, что уже произошло для большей ее части).
Есть такой полезный тип как std::function<signature>.
Стоит задача получения количества аргументов в сигнатуре функции и их типов. В compile time есс-но.
Почему-то в std::function я этого не нашел.
Что бы получить что-то типа этого:
template<TF>
std::function<void(int, value[])>
thunk( TF f ) {
switch(TF::argc) {
case 0: return [f](int argc, value argv[]) { f(); };
case 1: return [f](int argc, value argv[]) { f(argv[0].coerce<TF::argt<0>>() ); };
case 2: return [f](int argc, value argv[]) { f(argv[0].coerce<TF::argt<0>>(), argv[0].coerce<TF::argt<1>>() ); };
...
}
return [f](int argc, value argv[]) { assert(WTF); }
}
Т.е. из функции с произвольной сигнатурой получаем унифицированную функцию типа
void foo(int argc, value argv[])
Я что-то проглядел в std::function?
Есть вот такой вариант, но потому что гладиоус VS2010/12 он не подходит ибо variadic templates.
Что-то можно с этим сделать?
Re[2]: std::function<...> получение количества и типа параметров
Интересно, почему типы аргументов фнукции сделали через typedef see-below argN_type; вместо хранения всех типов аргументов в tuple или mpl::vector. Как в таком случае использовать n-ый аргумент в runtime? Допустим, у меня есть
typedef boost::variant<bool, int, std::string> argument;
typedef std::vector<argument> arguments;
template <typename F, size_t N>
struct call_helper
{
typedef boost::function_traits<F> F_traits;
F_traits::result_type exec(F function, arguments const& args);
};
// здесь куча специализаций, сгенерированных Boost.Preprocessor:
// call_helper<F, MAX_N>::exec(..),
// call_helper<F, MAX_N - 1>::exec(..),
// call_helper<F, 0>::exec(..)
// в которых делается конверсия args[i] к типу аргумента function и вызов function:
// return function(boost::get<arg_type<0>>(args[0]), boost::get<arg_type<1>>(args[1]), ... boost::get<arg_type<N-1>>(args[N-1]));template<typename F>
void call(F function, arguments const& args)
{
typedef boost::function_traits<F> F_traits;
if (args.size() != F_traits::arity)
{
throw std::runtime_error("argument count does not match function definition");
}
return call_helper<function, F_traits::arity>::exec(args);
}
Сейчас используется велосипед с boost::mpl::vector для arg_type и тип аргумента n я получаю c помощью boost::mpl::at_c<arg_type, n>
Про boost::function_traits я как-то не знал но даже зная теперь, не могу понять как его применять в данном случае.
Прдеполагаю, что в С+11 с variadic templates использование std::tuple для arg_type всё будет еще проще.
Re[4]: std::function<...> получение количества и типа параметров
J>>>это часть бустовских type_traits (т.е. в какой-то момент должна появиться и в std) J>>>http://www.boost.org/doc/libs/1_55_0/libs/type_traits/doc/html/boost_typetraits/reference/function_traits.html
PM>>Интересно, почему типы аргументов фнукции сделали через typedef see-below argN_type; вместо хранения всех типов аргументов в tuple или mpl::vector. Как в таком случае использовать n-ый аргумент в runtime? Допустим, у меня есть
J>Ну, если ты уже используешь Boost.Preprocessor, то нет проблем в нем же сгенерить и вызовы argN_type — заодно и компилиться будет быстрее
Спасибо, про Boost.FunctionTypes тоже не знал
Да, действительно, я могу нагенерировать препроцессором нужных argN_type. Но в перспективе включения function_traits в С++1z все равно не очень понятно, что делать с argN_type. Однако, если использовать std::tuple для типов аргументов функции, то получить n-й тип с использованием std::tuple_element в С++11 проще простого.