Search code examples
c++c++17template-meta-programming

Sfinae Templated Implicit Conversion Operator Overloads


I am trying to template a few conversion operator functions to accept various arithmetic types, namely signed / unsigned integer / floating point types, so there are 4 different function template definitions, a couple of which I have included.

template<typename UnsignedInteger>
operator std::enable_if_t<
            std::is_integral_v<UnsignedInteger> &&
            !std::is_signed_v<UnsignedInteger>,
            UnsignedInteger
> (){...}

template<typename SignedInteger>
std::enable_if_t<
            is_signed == true ||
            std::is_integral_v<SignedInteger> &&
            std::is_signed_v<SignedInteger>,
            SignedInteger
>operator (){...}

Their usage may look something like:

fixed<32, 1024> fixed = 32; // implicit constructor invoked, definition not included
uint64_t someFloat = fixed; // conversion invoked

I get the fairly generic error note: candidate template ignored: couldn't infer template argument 'UnsignedInteger' for this conversion, when I try to use implicit conversions.The conversion operator is created correctly when I remove the enable_if constraint, although only if on conversion function is present / implemented, naturally.

I only have access to c++ 17.

Thanks!


Solution

  • The problem is, packaging template parameter into std::enable_if makes it non-deduced context, template argument can't be deduced.

    You can move the condition to template parameter declaration. E.g.

    template<typename UnsignedInteger, std::enable_if_t<std::is_integral_v<UnsignedInteger> && !std::is_signed_v<UnsignedInteger>, void>* = nullptr>
    operator UnsignedInteger (){ ... }
    
    template<typename SignedInteger, std::enable_if_t<std::is_integral_v<SignedInteger> && std::is_signed_v<SignedInteger>, void>* = nullptr>
    operator SignedInteger (){ ... }
    

    LIVE