c++ - Recursive instantiation of a template with a typename? -


for templated function takes integer, wrote following general-purpose dispatcher:

#define dispatch_template(funct_name, max) \   template<int i> decltype(&funct_name<0>) dispatch_template_##funct_name (int index) {     \     return (index == i) ? funct_name <i> : dispatch_template_##funct_name <i - 1>(index);   \   } \   template<> decltype(&funct_name<0>) dispatch_template_##funct_name <-1>(int) {            \     return nullptr;                                                                         \   }                                                                                         \   decltype(&funct_name<0>) dispatch_##funct_name (int i) {                                  \     return dispatch_template_##funct_name <max>(i);                                         \   }                                                                                         \ 

this works , can this:

template<int some_int> void printint() {   printf("int %i\n", some_int); }  dispatch_template(printint, 6);  int main() {   (int = 0; < 6; ++i) {     dispatch_printint(i)();           }  return 0; } 

but if want pass typename parameter templated function?

for example, looks this:

template<int some_int, typename some_type> void printsometype(some_type arg) {   // } 

i want able this:

template<typename some_type> void caller(some_type arg) {   dispatch_template(printsometype, some_type, 6);   (int = 0; < 6; ++i) {     dispatch_printsometype(i)(arg);   } } 

i'm not sure how - i'm running issues "a template declaration not allowed here". (note dispatch_template here has inside function because function templated.)

you can't declarations work inside function because templates aren't allowed in block scope. dead end.

so need way declare outside of function instead.

turns out, macros evil, , rewriting macro template makes work.

#include <utility> #include <assert.h>        #include <iostream>  template<template<int, typename...> class func, typename... ts> class dispatcher { public:   using function_ptr = decltype(&func<0, ts...>::call);    template<int max=10>   static function_ptr get_func(int i) {       assert(i>=0 && i<max);       return get_func_impl(i, std::make_integer_sequence<int, max>());   }  private:   template<int... vals>   static function_ptr get_func_impl(int i, std::integer_sequence<int, vals...> ) {       static constexpr function_ptr funcs[] = {&func<vals, ts...>::call...};       return funcs[i];   }  };  template <int i, typename t> struct foo {     static void call(t val) {         std::cout << "hello foo " << << " " << val << std::endl;     } };  int main() {     dispatcher<foo, double>::get_func<>(5)(2.3); // output: hello foo 5 2.3 } 

last step create macro required template <...> struct x { call(); }; format. required because can't pass template function template.

note: std::integer_sequence c++14 only, can add polyfill implementation, e.g. here. trying implement without messy nested partially-specialised structs, because can't specialize functions inside template.


Comments

Popular posts from this blog

php - Permission denied. Laravel linux server -

google bigquery - Delta between query execution time and Java query call to finish -

python - Pandas two dataframes multiplication? -