Reputation: 25
I have a number of bitmasks to add (layer, logical OR |
), but as they are constants I would like to do so at compile time. Entering advanced template territory...
I tried recursion:
template <uint8_t mask, uint8_t...masks>
struct MaskAdd {
static const uint8_t value = masks | MaskAdd<masks>::value;
};
template <uint8_t mask>
struct MaskAdd {
static const uint8_t value = mask;
};
which gave the following errors:
file.cpp:3:55: error: parameter packs not expanded with ‘...’:
static const uint8_t value = masks | MaskAdd<masks>::value;
^
file.cpp:3:55: note: ‘masks’
file.cpp:7:8: error: redeclared with 1 template parameter
struct MaskAdd {
^
file.cpp:2:8: note: previous declaration ‘template<unsigned char mask, unsigned char ...masks> struct MaskAdd’ used 2 template parameters
struct MaskAdd {
^
I also tried this strange syntax, given by (presumably) a misunderstanding of the cppreference page on parameter packs:
template <uint8_t...masks>
struct MaskAdd {
static const uint8_t value = (masks | ...);
};
which threw these errors:
file.cpp:3:43: error: expected primary-expression before ‘...’ token
static const uint8_t value = (masks | ...);
^
file.cpp:3:43: error: expected ‘)’ before ‘...’ token
I've got a feeling the solution is somewhere in the template<template<
region of hell, if anyone can explain those I'd be grateful.
Upvotes: 2
Views: 850
Reputation: 1
This is my aproach for a compile time mask... First templated parameter is the position of the bit counting from right, the second is the number of bits set as 1 towards left.
template <unsigned START, unsigned RANGE>
struct Mask
{
static const size_t val = 1 << START | Mask<START + 1, RANGE - 1>::val;
};
template <unsigned START>
struct Mask<START, 0>
{
static const size_t val = 0;
};
If I want to create a mask with, for example, number 14 (0000 1110):
unsigned mask = Mask<1, 3>::val;
Upvotes: 0
Reputation: 19617
You have typo(s) in this expression:
masks | MaskAdd<masks>::value
It should be:
mask | MaskAdd<masks...>::value
// ^ no 's' ^ the expansion compiler was talking about
Then it will complain about the redeclaration of the class, so provide a specialization instead (for a single parameter):
template <uint8_t mask>
struct MaskAdd<mask> { .. };
Upvotes: 4