枚举值能否用于std::integer_sequence?标准合规性与编译器差异咨询
关于std::integer_sequence使用枚举类型的C++标准合规性问题
一段代码在GCC 13和Clang 17中可正常编译运行,但在MSVC中编译失败,需确认该代码是否符合C++标准要求,或是MSVC存在兼容性问题。
原代码
#include <utility> #include <iostream> enum e : int { A=5, B, C, D }; auto x = std::integer_sequence<e, A, B, C, D>{}; auto y = std::integer_sequence<unsigned, 9, 4, 3, 8>{}; auto z = std::integer_sequence<int, 0, 1, 2, 3>{}; template<typename T, T... ints> void print_sequence(std::integer_sequence<T, ints...> int_seq) { std::cout << "The sequence of size " << int_seq.size() << ": "; ((std::cout << ints << ' '), ...); std::cout << '\n'; } int main(int, char**) { print_sequence(x); print_sequence(y); print_sequence(z); return 0; }
MSVC报错信息
error C2338: static_assert failed: 'integer_sequence<T, I...> requires T to be an integral type.'
问题分析与结论
- C++标准要求:根据C++标准,
std::integer_sequence的模板参数T必须是整数类型(integral type)。而带固定底层类型的枚举(如示例中的enum e : int)属于枚举类型(enumeration type),并不属于标准定义的整数类型范畴。 - 编译器行为差异:
- GCC和Clang对标准做了扩展实现,允许将带有底层整数类型的枚举视为整数类型的等价物,因此可以编译通过这段代码。
- MSVC严格遵循标准的要求,通过
static_assert检查T是否为整数类型,因此抛出编译错误。
- 结论:这段代码不符合C++标准要求,MSVC的报错是合规的行为,GCC和Clang的支持属于编译器扩展。
兼容各编译器的修改方案
若要让代码在所有主流编译器中兼容,需将std::integer_sequence的模板参数改为枚举的底层整数类型(示例中为int),枚举值可隐式转换为底层整数类型,修改后的代码如下:
#include <utility> #include <iostream> enum e : int { A=5, B, C, D }; // 将模板参数改为枚举的底层类型int auto x = std::integer_sequence<int, A, B, C, D>{}; auto y = std::integer_sequence<unsigned, 9, 4, 3, 8>{}; auto z = std::integer_sequence<int, 0, 1, 2, 3>{}; template<typename T, T... ints> void print_sequence(std::integer_sequence<T, ints...> int_seq) { std::cout << "The sequence of size " << int_seq.size() << ": "; ((std::cout << ints << ' '), ...); std::cout << '\n'; } int main(int, char**) { print_sequence(x); print_sequence(y); print_sequence(z); return 0; }
内容的提问来源于stack exchange,提问作者jtl313
相关产品推荐
相关产品推荐

