c++ - Type definition should be dependent on template parameters -


given template class a, want define type t_res depending on a's template parameters t_lhs , t_rhs:

template< typename t_lhs, typename t_rhs > class {   // definition of t_res in case "t_lhs , t_rhs both not primitive types"   template< bool lhs_is_fundamental = std::is_fundamental<t_lhs>::value,             bool rhs_is_fundamental = std::is_fundamental<t_rhs>::value,             std::enable_if_t<( !lhs_is_fundamental && !rhs_is_fundamental )>* = nullptr >   using t_res = decltype( std::declval<t_lhs>().cast_to_primitive() / std::declval<t_rhs>().cast_to_primitive() );    // definition of t_res in case "t_lhs and/or t_rhs primitive type"   template< bool lhs_is_fundamental = std::is_fundamental<t_lhs>::value,             bool rhs_is_fundamental = std::is_fundamental<t_rhs>::value,             std::enable_if_t<( lhs_is_fundamental || rhs_is_fundamental )>* = nullptr >   using t_res = decltype( std::declval<t_lhs>() / std::declval<t_rhs>() );    // ... }; 

in first case, t_lhs , t_rhs both not primitiv types, code designed represent classes implement function cast_to_primitive()that returns primitive type; in first case, want t_res have type obtained dividing element of type decltype( std::declval<t_lhs>().cast_to_primitive() ) element of type decltype( std::declval<t_rhs>().cast_to_primitive() ).

in second, either t_lhs or t_rhs primitive type (or both) , want t_res have type obtained dividing element of type t_lhs element of type t_rhs. example, in case t_lhs primitive type, code designed t_rhs can implicitly casted element of type t_lhs; same applies in case t_rhs primitive.

unfortunately, code above not compile. error:

error: template non-type parameter has different type 'std::enable_if_t<(lhs_is_fundamental || rhs_is_fundamental)> *' (aka 'typename enable_if<(lhs_is_fundamental || rhs_is_fundamental), void>::type *') in template redeclaration             std::enable_if_t<( lhs_is_fundamental || rhs_is_fundamental )>* = nullptr >                                                                             ^ note: previous non-type template parameter type 'std::enable_if_t<(!lhs_is_fundamental && !rhs_is_fundamental)> *' (aka 'typename enable_if<(!lhs_is_fundamental && !rhs_is_fundamental), void>::type *') here             std::enable_if_t<( !lhs_is_fundamental && !rhs_is_fundamental )>* = nullptr >                                                                               ^ 

can me fix problem?

this same problem found in using std::conditional_t define class' typedef in dependence of template parameter

the solution use std::conditional along helper classes delay instantiation of division/call cast_to_primitive until after std::conditional instantiated:

#include <type_traits>  template<class t1, class t2> struct {   template<class t=t1, class u=t2>   struct cast_to_primitive_t {using type=decltype(std::declval<t>().cast_to_primitive() / std::declval<u>().cast_to_primitive());};   template<class t=t1, class u=t2>   struct primitive_div_t {using type=decltype(std::declval<t>() / std::declval<u>());};    using t_res = typename std::conditional_t<std::is_fundamental<t1>{} && std::is_fundamental<t2>{}, primitive_div_t<>, cast_to_primitive_t<>>::type; }; 

Comments

Popular posts from this blog

asynchronous - C# WinSCP .NET assembly: How to upload multiple files asynchronously -

aws api gateway - SerializationException in posting new Records via Dynamodb Proxy Service in API -

asp.net - Problems sending emails from forum -