У меня есть структура Opers
с некоторыми арифметическими операциями: mult()
, div()
, mod()
,
И мне нужно специализировать шаблон для определенных значений n
, Вот пример для Opers<1>
,
Но также я хочу сделать специализацию для n
это степени 2 (n = 2,4,8,16, …) — в этом случае я могу оптимизировать операции mult()
а также div()
(используя битовый сдвиг влево или вправо).
#include <iostream>
using namespace std;
template<int n> struct Opers {
int mult(int x){
return n*x;
}
int div(int x){
return x / n;
}
int mod(int x){
return x % n;
}
};
template<> struct Opers<1> {
int mult(int x){
return 1;
}
int div(int x){
return x;
}
int mod(int x){
return 0;
}
};
int main() {
Opers<1> el2;
cout << el2.mult(3) <<endl;
}
Я ищу конструкцию как
template<> struct Opers<isPowerOfTwo()>
int mult(int x){
// do smth
}
Возможно ли это или какое руководство следует прочитать?
UPD. Использование C ++ 11 разрешено, и даже будет лучше.
В C ++ 11 вы могли бы сделать это таким образом. Прежде всего, измените ваш основной шаблон так, чтобы он принимал второй, фиктивный параметр:
template<int n, typename = void>
struct Opers
{
// ...
};
Затем напишите constexpr
функция, которая определяет, является ли целое число степенью 2:
constexpr bool is_power_of_two(int x)
{
return (x == 1) || ((x % 2 == 0) && is_power_of_two(x / 2));
}
Наконец, используйте SFINAE, чтобы включить или отключить специализацию на основе результатов вашего constexpr
функция:
#include <type_traits>
template<int n>
struct Opers<n, typename std::enable_if<is_power_of_two(n)>::type>
{
// ...
};
template <int N, typename = void>
struct Operations
{
// ....
};
template <int N, typename = std::enable_if<(N & (N - 1))>::type>
struct Operations
{
// ....
};