samedi 25 avril 2015

Disable Function when parameter type is void

I have a template class looking like this:

template <typename T> constexpr bool is_value_passable_v = is_trivially_copyable_v<T> && sizeof(T) <= sizeof(void*) && !is_polymorphic_v<T>;
template <typename B, typename T> using param_base_t = conditional_t<is_value_passable_v<B>, T, const T&>;

template <typename T> struct param_d
{
    using type = param_base_t<T, T>;
};

template <> struct param_d<void>
{
    using type = void;
};

template <typename T> using param_t = typename param_d<T>::type;

template <class TIn> class CClass
{
    public:
        static constexpr bool use_input_v = !is_same_v<typename TIn::input_t, void>;
        using input_t = conditional_t<use_input_v, param_t<typename TIn::input_t>, void>;

        enable_if_t<use_input_v> Input(input_t i);
};

The goal of this code is, to provde different Input functions for different template paramters.

  • A template parameter with input_t = int should result in void Input(int i)
  • A template parameter with input_t = std::vector should result in void Input(const std::vector& i)
  • A template parameter with input_t = void should remove the Input function

Compiling this with clang gives

/usr/bin/../include/c++/v1/type_traits:225:78: error: no type named 'type' in 'std::__1::enable_if<false, void>'; 'enable_if' cannot be used to disable this declaration
template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type;
                                                                             ^~~

Edit 1: After adding the line

template <typename T> static constexpr bool use_input2_v = use_input_v;

and replacing the function declaration with

template <typename T = void> enable_if_t<use_input2_v<T>> Input(input_t i)

clang complains there's no matching member function for call to 'Input':

note: candidate template ignored: substitution failure [with T = void]: non-type template argument is not a constant expression
template <typename T = void> enable_if_t<use_input2_v<T>> Input(input_t i);
                                         ~~~~~~~~~~~~     ^

Edit 2: Forgot to mention, that this error comes with all three variants of template parameters.

Aucun commentaire:

Enregistrer un commentaire