I'm currently trying to make a variadic templated function named MakeByte
that will take any number of arguments of bits, and put them into one byte. Here's an example of the usage for it:
// The Wii U has 4 RAM chips, here we select a seemingly "random" one using an
// algorithm to generate one from the coordinates.
quint32 bank_bit_0 = Bit((y / (16 * m_num_pipes)) ^ x_3);
quint32 bank_bit_1 = Bit((y / (8 * m_num_pipes)) ^ x_4);
quint32 bank = MakeByte(bank_bit_0, bank_bit_1);
I have three functions, in a separate header involved:
template <typename T1, typename... T2> T1 MakeByte(T1 bit, T2... bits)
, the function that will be used by external code that calls the recursive functions.template <typename T1, typename... T2> T1 MakeByte(T1 byte, quint32 pos, T1 bit, T2... bits)
, the recursive function that iterates over each bit. This function has additional arguments to keep track of the final byte, and the current position to put the next bit in.template <typename T1, typename T2> T1 MakeByte(T1 byte, quint32 pos, T2 bit)
, the function that deals with the final bit.
Here's the complete 3 definitions:
template <typename T1, typename T2>
constexpr T1 MakeByte(T1 byte, quint32 pos, T2 bit)
{
return byte | (bit << pos);
}
template <typename T1, typename... T2>
constexpr T1 MakeByte(T1 byte, quint32 pos, T1 bit, T2... bits)
{
return MakeByte(byte | (bit << pos), pos + 1, bit, bits...);
}
template <typename T1, typename... T2>
constexpr T1 MakeByte(T1 bit, T2... bits)
{
return MakeByte(static_cast<T1>(0), 0, bit, bits...);
}
The issue is that, when compiling with g++, I get this error:
/home/kyle/Documents/Projects/C++/Qt/MK8Studio/Source/Common.h:44: error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum)
return MakeByte(static_cast<T1>(0), 0, bit, bits...);
~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
At this point, I renamed the two recursive functions, in case there was ambiguity:
template <typename T1, typename T2>
constexpr T1 MakeByte_(T1 byte, quint32 pos, T2 bit)
{
return byte | (bit << pos);
}
template <typename T1, typename... T2>
constexpr T1 MakeByte_(T1 byte, quint32 pos, T1 bit, T2... bits)
{
return MakeByte_(byte | (bit << pos), pos + 1, bit, bits...);
}
template <typename T1, typename... T2>
constexpr T1 MakeByte(T1 bit, T2... bits)
{
return MakeByte_(static_cast<T1>(0), 0, bit, bits...);
}
This code does compile, but I can't help but feel this is a bit of a hack. From a design perspective, what is the best way to reduce ambiguity within variadic templated functions?
Aucun commentaire:
Enregistrer un commentaire