Условное числовое ограничение на аргумент шаблона

У меня есть шаблон для структуры данных / контейнера, оптимизированный для размеров в степени 2, и он не будет работать должным образом, если параметр размера не является степенью 2.

template <typename T, unsigned int __pow2int>
class CustomContainer {
}

Каков наилучший способ / возможно ли это вообще … выполнить проверку во время компиляции, чтобы убедиться, что __pow2int имеет степень 2?

Я новичок в C ++, и я смотрю на такие страницы: http://www.stroustrup.com/bs_faq2.html#constraints но я нахожу синтаксис, такой как …

static void constraints(T1 a, T2 b) { T2 c = a; b = a; }
Can_copy() { void(*p)(T1,T2) = constraints; }

Полностью сбивающий с толку, я даже не уверен, что так можно достичь того, чего я пытаюсь достичь, я совершенно заблудился, пытаясь следовать этим часто задаваемым вопросам.

На мой взгляд, возможно, мне следует объявить определяемый пользователем тип, который создает степень только 2 целых чисел, и использовать его как тип шаблона?

Я пытался реализовать это, но в итоге я получил сообщение об ошибке «Параметр шаблона нестандартного типа не может…».

class intb2 {
const std::uint32_t _output;
public:
intb2(std::uint8_t bit) : _output([&]() {
uint8_t rbit=(bit == 0) ? 1 : bit;
std::uint32_t i=1;
return (i << (rbit-1));
}()) {}

const std::uint32_t& operator()() {
return _output;
}
};

template <typename T, intb2 __pow2int>
class CustomContainer {....

2

Решение

Обычный трюк, чтобы проверить, есть ли номер x является степенью двойки поразрядно-и это с x-1 и посмотреть, если результат равен нулю:

x != 0 && (x & (x−1)) == 0

Теперь используйте это в объявление статического утверждения:

template <typename T, unsigned int N>
class CustomContainer {
static_assert( N != 0 && (N & (N−1)) == 0 , "Not a power of two!");
};
5

Другие решения

Самый простой способ решить эту проблему — использовать показатель степени в качестве аргумента.

template <typename T, unsigned int exp>
class CustomContainer
{
unsigned int __pow2int = 1<<exp;

};
1