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