Variadic template expansion with aliases?

  alias, c++, c++20, templates

So in a codebase I inherited we have a messy utility file along the lines of:

template <typename T, std::enable_if_t<(sizeof(T) == 1)>> int doA(const T *Data, size_t Size);
template <typename T, std::enable_if_t<(sizeof(T) == 1)>> int doB(const T *Data, size_t Size);

template <typename T> int doA(T &Input) 
{ return doA<uint8_t>((uint8_t *)&Input, sizeof(T); };
template <typename T, size_t N> int doA(T(&Input)[N]) 
{ return doA(Input, N - 1); };

template <typename T> int doA(std::vector<T> Input) 
{ return doA((uint8_t *)Input.data(), sizeof(T::value_type) * Input.size()); };
/* Repeat for doB */

So I figured that since doA and doB were pretty similar, one could reduce the mess to:

template <bool TypeA, typename T, std::enable_if_t<(sizeof(T) == 1)>> 
int do_t(const T *Data, size_t Size) { if constexpr(TypeA) ... };

template <bool TypeA, typename T> int do_t(T &Input) 
{ return do_t<TypeA, uint8_t>((uint8_t *)&Input, sizeof(T); };
template <bool TypeA, typename T, size_t N> int do_t(T(&Input)[N]) 
{ return do_t<TypeA, T>(Input, N - 1); };

template <bool TypeA, typename T> int do_t(std::vector<T> Input) 
{ return do_t<TypeA, uint8_t>((uint8_t *)Input.data(), sizeof(T::value_type) * Input.size()); };

template <typename ...Args> using doA = do_t<true, Args...>;
template <typename ...Args> using doB = do_t<false, Args...>;

// Expand to do_t<true, char, 4>(char (&Input)[4])
static_assert(doA("abc") == 123);

// Expand to do_t<false, int>(int &Input)
static_assert(doB(321) == 123);

Naturally that didn’t work out with the compiler complaining that do_t is undefined at the alias. What’s the proper approach to something like this where you want to capture all overloads?

Source: Windows Questions C++

LEAVE A COMMENT