c++11 - Compile-time selection of function pointer -


i have compile-time selection of function pointers. functionlistautomatic in following

int funk( int a, int b ) { return * b / 2; }  template< typename t0, typename t1 > int null_func( t0 a, t1 b ) { return 0; }  tuple< int( *)(int, int), int( *)(int, float) > functionlist {     funk,     null_func<int, float> };  // pseudo code. tuple< int( *)(int, int), int( *)(int, float) > functionlistautomatic {     condition( funk_exist( funk( int, int ) )   , funk, null_func<int, int> ),     condition( funk_exist( funk( int, string ) ), funk, null_func<int, string> ), };  void main() {     int res0 = get<0>( functionlist )(1, 2);     int res1 = get<1>( functionlist )(1, 2); } 

i cannot figure out how this.

i know how make funk_exist evaluates @ compile time (i use variant of this: https://en.wikibooks.org/wiki/more_c++_idioms/member_detector). 2 parameters funk , null_func causes problem. compiler tries find funk( int, string ) function , fails before evaluates funk_exist(). need expression evaluates funk_exist() , not evaluate funk( int, string ) if funk_exist() evaluates false.

appreciate help.

namespace details {   template<class...>struct voider{using type=void;};   template<class...ts>using void_t=typename voider<ts...>::type;    template<template<class...>class z, class, class...ts>   struct can_apply:std::false_type{};   template<template<class...>class z, class...ts>   struct can_apply<z,void_t<z<ts...>>,ts...>:std::true_type{}; } template<template<class...>class z, class...ts> using can_apply=details::can_apply<z,void,ts...>; 

boilerplate injected!1

adding funk:

template<class...ts> funk_r = decltype(funk(std::declval<ts>()...)); template<class...ts> can_funk = can_apply<funk_r, ts...>; 

now know if can funk.

but funk? funk_miester:

template<class lhs, class rhs, class=void> struct funk_miester {   decltype(null_func<lhs,rhs>) operator()()const{     return null_func<lhs, rhs>;   } }; template<class lhs, class rhs> struct funk_miester<lhs, rhs, std::enable_if_t< can_funk<lhs,rhs>{} >> {   funk_r<lhs,rhs>(*)(lhs, rhs) operator()()const{     return [](lhs l, rhs r)->funk_r<lhs,rhs> {       return funk(l,r);     };   } }; 

and down below line see result:

tuple< int( *)(int, int), int( *)(int, float) > functionlistautomatic (   funk_miester<int,int>{}(),   funk_miester<int,string>{}() ); 

and funkey.

note check if funk can called in can_funk, can replace whatever trait want, long generates compile-time bool.

in case, lambda acts adapter, if signatures don't match still generate function pointer.


1 gives me trait detect if can call funk on arguments. have own, don't have use it.


Comments

Popular posts from this blog

searchKeyword not working in AngularJS filter -

sequelize.js - Sequelize: sort by enum cases -

user interface - how to replace an ongoing process of image capture from another process call over the same ImageLabel in python's GUI TKinter -