Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

partial template specialization with enable_if

I am trying to create a function and constrain it to is_trait_types which is defined as:

template <typename T>
struct is_trait_type : std::false_type
{
};

template <>
struct is_trait_type<my_type> : std::true_type
{
};

I want to provide a default implementation for all is_trait_types and then using partial specialization custom behavior for other_types (which obviously are also is_trait_types.

This is the function in question:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

// default impl for all is_trait_types
template <typename T, std::enable_if_t<is_trait_type<T>{}, int> = 0>
inline bool should_delay_aggregation(typename T::aggregation, const typename T::type&)
{
    return false;
}

// partial specialization for other_types
template<>
inline bool should_delay_aggregation<other_type>(other_type::aggregation, const other_type::type&)
{
    return some logic with aggregation and type;
}

But I can’t get it to compile I get the classic template-id ‘should_delay_aggregation<other_type>’ for ‘bool should_delay_aggregation(other_type::aggregation, const other_type::type&)’ does not match any template declaration, candidate is: ‘template<class T, typename std::enable_if<is_trait_type<T>{}, int>::type <anonymous> > bool should_delay_aggregation(typename T::aggregation, const typename T::type&)

I do need to use std::enable_if since I using C++14. I know that with concepts this would be much easier, but I am not too familiar with std::enable_if.

Thanks in advance.

>Solution :

There are no partial specializations of function templates (Why function template cannot be partially specialized?), and even if there were, you wouldn’t be using the right syntax.

You could write a full specialization of a function template:

template <typename T>
auto should_delay_aggregation(typename T::aggregation, const typename T::type&)
  -> std::enable_if_t<is_trait_type<T>{}, bool>
{
    return false;
}

// note: if you remove template <>, this simply becomes an overload instead
//       of a full specialization, which is also okay
template <>
bool should_delay_aggregation(other_type::aggregation, const other_type::type&)
{
    return /* ... */;
}

However, this isn’t very idiomatic; type traits are usually implemented as a class for multiple reasons, and this would also allow you to avoid std::enable_if_t:

template <bool B> // use std::bool_constant in C++17
using bool_constant = std::integral_constant<bool, B>;

// primary template
template <typename T> 
struct should_delay_aggregation : bool_constant<std::is_same<T, my_type>::value> {};
// note: is_trait_type can be simplified to std:is_same<T, my_type>

// full specialization for other_type
template <>
struct should_delay_aggregation<other_type> : bool_constant</* some logic here */> {};

// other partial specializations are also possible ...

// usage:
static_assert(should_delay_aggregation<other_type>::value, ":(");
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading