c++ - Iterating through function_traits arguments -
i'm trying "template metaprogramming" stuff make exposing c++ functions python bit easier. i'd take existing function , generating string containing info return type , arguments (a typeinfo fine too).
i'm using function traits class based off (stolen from) this wordpress article, rather hard code accesses first few arguments i'd iterate through them all.
i gather need make template function takes size_t value argument index (since must constant), that's bit lost.
i've written code, can't work in basic of cases (let alone generic case i'm after.)
// stolen function_traits struct...thing 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); using result_type = r; template <size_t i> struct arg { using type = typename std::tuple_element<i, std::tuple<args...>>::type; }; }; // function of interest int foo(float x) { return int(x); } // recurse until 1 argument left, appending type name // referenced string being passed in template<size_t argidx, typename r, typename ... args> void getargtypes(std::string& ref) { using fun = function_traits<std::function<r(args...)> >; if (argidx == 1) ref.append(typeid(fun::arg<0>).name()).append("\n"); else { ref.append(typeid(fun::arg<argidx-1>).name()).append("\n"); getargtypes<argidx - 1, r, args...>(ref); } } // test of template function void test() { std::string f = ""; // i'd using fun = function_traits<std::function<decltype(foo)> >; getargtypes<fun::nargs, fun::result_type, ? ? ? >; // can't this! getargtypes<1, float, int>(f); }
in first case, use function_traits struct when calling getargtypes, don't know designate ... args template parameter. in second case msvc throws error:
error c1202 recursive type or function dependency context complex
i'm new metaprogramming / variadic templates stuff sorry if dumb question. if there's less roundabout solution i'd interested.
thank reading!
if (argidx == 1)
can't runtime condtion. must changed compile time 1std::enable_if
. error comes from: compiler tries instantiate endlessly (recursively without stop condition)getargtype
function template.all dependent type names must announced
typename
keyword, , refer templates must announcedtemplate
keyword, e.g.typename fun::template arg<0>
in place offun::arg<0>
.fun::arg<0>
struct nestedtype
definition. access it, usetypename fun::template arg<0>::type
syntax.expansion of
function_traits::arg<n>::type
can done indices trick, in particulartypename f::template arg<is>::type...
.
#include <string> #include <typeinfo> #include <functional> #include <utility> #include <cstddef> template <size_t argidx, typename r, typename... args> auto getargtypes(std::string& ref) -> typename std::enable_if<argidx == 1>::type { using fun = function_traits<std::function<r(args...)> >; ref.append(typeid(typename fun::template arg<0>::type).name()).append(" "); } template <size_t argidx, typename r, typename... args> auto getargtypes(std::string& ref) -> typename std::enable_if<argidx != 1>::type { using fun = function_traits<std::function<r(args...)> >; ref.append(typeid(typename fun::template arg<argidx-1>::type).name()).append(" "); getargtypes<argidx - 1, r, args...>(ref); } template <typename f, std::size_t... is> void test2(std::index_sequence<is...>) { std::string s; getargtypes<f::nargs, typename f::result_type, typename f::template arg<is>::type...>(s); std::cout << s; } void test() { using f = function_traits<std::function<decltype(foo)>>; test2<f>(std::make_index_sequence<f::nargs>{}); }
very basic index_sequence
implementation goes follows:
template <std::size_t...> struct index_sequence {}; template <std::size_t n, std::size_t... is> struct make_index_sequence : make_index_sequence<n-1, n-1, is...> {}; template <std::size_t... is> struct make_index_sequence<0, is...> : index_sequence<is...> {};
Comments
Post a Comment