It looks like it might work.
Code:
#include <iostream>
uint32_t a[2]
{
0x11223344, // 00010001 00100010 00110011 01000100
// ^^^^^ FieldA = 8
0x55667788 // 01010101 01100110 01110111 10001000
// ^^^^ ^^^ FieldB = 60
};
template <uint32_t Addr, uint8_t StartBit, uint8_t NumBits>
struct Field
{
constexpr static uint32_t addr{Addr};
constexpr static uint8_t startBit{StartBit};
constexpr static uint8_t numBits{NumBits};
};
using FieldA = Field<0, 3, 5>;
using FieldB = Field<1, 5, 7>;
template<typename T>
uint32_t ReadField()
{
constexpr T v;
return (a[v.addr] >> v.startBit) & ((1 << v.numBits) - 1);
}
int main()
{
std::cout << ReadField<FieldA>() << '\n';
std::cout << ReadField<FieldB>() << '\n';
}