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!

  1. if (argidx == 1) can't runtime condtion. must changed compile time 1 std::enable_if. error comes from: compiler tries instantiate endlessly (recursively without stop condition) getargtype function template.

  2. all dependent type names must announced typename keyword, , refer templates must announced template keyword, e.g. typename fun::template arg<0> in place of fun::arg<0>.

  3. fun::arg<0> struct nested type definition. access it, use typename fun::template arg<0>::type syntax.

  4. expansion of function_traits::arg<n>::type can done indices trick, in particular typename 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>{}); } 

demo


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

Popular posts from this blog

php - Admin SDK -- get information about the group -

dns - How To Use Custom Nameserver On Free Cloudflare? -

Python Error - TypeError: input expected at most 1 arguments, got 3 -