[英]Is it possible to iterate through enum members in a constexpr function, so the values are constexpr?
假设我想创建一个可以将可变宽度整数存储在一起的通用系统。 在这个系统中,我们可以使用一个enum
,它包含成员名称(这个 enum 成员有连续的值[0;count)
):
enum class Group1 {
AttrA,
AttrB,
AttrC,
};
我添加了inline constexpr
专业化,它告诉我们有多少成员:
template <typename TYPE>
inline constexpr int count = -1;
template <>
inline constexpr int count<Group1> = 3; // Group1 has 3 members (AttrA/B/C)
我添加了描述每个成员宽度的inline constexpr
专业化:
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;
现在,我想要一个通用的constexpr
函数,它可以计算总宽度(任何类型,而不仅仅是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;
}
但是,这不会编译,因为r += nBits...
行:
错误:非类型模板参数不是常量表达式
是否可以创建可编译的summedWidth()
函数(或提供编译时常量的任何其他解决方案)?
使用std::make_integer_sequence
将count<TYPE>
展开成一个可以折叠的包:
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 链接: http ://coliru.stacked-crooked.com/a/28df4b17d071f6e5
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.