3

Suppose that I want to create a general system which can store variable-width integers together. In this system, we can use an enum, which contain member names (this enum members have consecutive values [0;count)):

enum class Group1 {
    AttrA,
    AttrB,
    AttrC,
};

I add inline constexpr specialization, which tells, how many members are there:

template <typename TYPE>
inline constexpr int count = -1;

template <>
inline constexpr int count<Group1> = 3; // Group1 has 3 members (AttrA/B/C)

And I add inline constexpr specializations which describes each members width:

template <auto VALUE>
inline constexpr int nBits = -1;

template <>
inline constexpr int nBits<Group1::AttrA> = 3; // AttrA need 3 bits of storage
template <>
inline constexpr int nBits<Group1::AttrB> = 2;
template <>
inline constexpr int nBits<Group1::AttrC> = 4;

Now, I'd like to have a general constexpr function , which can calculate summed width (of any type, not just Group1):

template <typename TYPE>
constexpr int summedWidth() {
    int r = 0;
    for (int i=0; i<count<TYPE>; i++) {
        r += nBits<static_cast<TYPE>(i)>;
    }
    return r;
}

However, this doesn't compile, because of the r += nBits... line:

error: non-type template argument is not a constant expression

Is it possible to create a compilable summedWidth() function (or any other solution, which provides a compile-time constant)?

0

1 Answer 1

2

Use std::make_integer_sequence to expand count<TYPE> into a pack that you can fold over:

template <typename TYPE, int... ints>
constexpr int summedWidthHelper(std::integer_sequence<int, ints...>) {
    return (0 + ... + nBits<static_cast<TYPE>(ints)>);
}

template <typename TYPE>
constexpr int summedWidth() {
    return summedWidthHelper<TYPE>(std::make_integer_sequence<int, count<TYPE>>{});
}

Coliru link: http://coliru.stacked-crooked.com/a/28df4b17d071f6e5

Sign up to request clarification or add additional context in comments.

1 Comment

Why not just use std::index_sequence?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.