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
Post a Comment