I use in my project such a function for counting leading zeros, the aim for it is to work with any non container type and to return a constant expression, so that I could use it's results for other templates.
template <typename T>
consteval int CountLeadingZeros(const T& DATA) {
T MASK{ 1 };
int BITSN{ sizeof(T) * CHAR_BIT },
LEADINGN{ 0 };
MASK <<= BITSN - 1;
for (int I = BITSN; I > 0; I--, LEADINGN++, MASK >>= 1) {
if (DATA & MASK) {
break;
}
}
return LEADINGN;
}
But of cause it doesn't return a real const expression. If you'll try to use it, there will be an error:
constexpr int value = CountLeadingZeros <const int> (100);
Error:
E3133 call to consteval function "fsm::CountLeadingZeros(const T &DATA) [with T=const int]" did not produce a valid constant expression
On the other hand C++20 countl_zero() works perfect and returns constexpr. But it can not work with anything except uint8_t.
Help me please to fight and win this E3133 error. How could I make my function working in compile time?
Don't pass const int
as the template argument. Replace it with just int
. Currently, MASK
gets declared as const int MASK = 1
, and then you try to modify it, which obviously doesn't work. Otherwise, the function should be constant-evaluatable