Search code examples
c++templatesmetaprogrammingtemplate-meta-programming

There is any way to do a partial specialization?


Just for fun I'm trying to implement a compile-time pow2 function with templates. Actually, I'm able to do it, this way:

template <std::size_t n, typename type_t>
struct custom
{
    static type_t pow(type_t b) { return b * custom<n - 1, type_t>::pow(b); }
};

template <typename type_t>
struct custom<0, type_t>
{
    // (void)b; to avoid unused warning.
    static type_t pow(type_t b) { (void) b; return static_cast<type_t>(1); }
};

And that way, it works, but my aproach was to think in something more like this:

template <std::size_t n, typename type_t>
type_t cus_pow(type_t b) { return b * cus_pow<n - 1, type_t>(b); }

// This doesn't exists.
template <0, typename type_t>
type_t cus_pow(type_t b) { (void) b; return 1; }

Because if I want to create any partial metaprogramming function, beeing forced to create a struct it looks too much.

So, there is any way to do partial metaprogramming just with one function?


Solution

  • You cannot partially specialize function/method.

    You can use if constexpr (C++17) to avoid repetition though:

    static type_t pow([[maybe_unused]]type_t b) {
        if constexpr (n == 0) {
            return static_cast<type_t>(1); }
        } else {
            return b * custom<n - 1, type_t>::pow(b);
        }
    }
    

    No extra runtime branching.