c++ std::integer_sequence中是否允许枚举值?

1u4esq0p  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(91)

这段代码使用GCC 13和Clang 17编译和执行都很好,但在MSVC上编译失败。我想知道这段代码是否需要根据标准工作,或者这是MSVC的问题。Demo

#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给出此错误:
错误C2338:static_assert失败:'integer_sequence<T,I...>要求T为整型'。

s1ag04yj

s1ag04yj1#

MSVC-STL和libc++†是正确的,因为e不是整数类型(即std::is_integral_v<e>false)。
intseq.intseq(https://eel.is/c++draft/intseq.intseq)开始:

namespace std {
  template<class T, T... I> struct integer_sequence {
    using value_type = T;
    static constexpr size_t size() noexcept { return sizeof...(I); }
  };
}

字符串

  • Mandates*:T是一个整数类型。

值得注意的是,相比之下,integral_constantT没有要求,所以像integral_constant<pair<int, int>, pair{0, 0}>这样的东西在C20中完全可以。
† Clang的libc
需要通过-stdlib=libc++标志启用,在integer_sequence实现中也有一个corresponding static_assert

ruoxqz4g

ruoxqz4g2#

Clang和gcc在接受程序时是错误的,因为e不是整数类型(static_assert(std::is_integral_v<e>)将失败),并且std::integer_sequence的第一个模板参数必须是整数类型。

std::integer_sequence

template< class T, T... Ints >
class integer_sequence;   (since C++14)

字符串
模板参数T-用于序列元素的整数类型
并且从整数类型
类型char、wchar_t、char8_t、char16_t和char32_t统称为字符类型。字符类型、bool、有符号和无符号整数类型及其cv限定版本([basic.type.qualifier])统称为整型。整型的同义词是integer type
你也可以使用static_assert来检查:

static_assert(std::is_integral_v<e>); //msvc, gcc and clang all fail this as expected

解决方法

可以使用std::underlying_type

auto x = std::integer_sequence<std::underlying_type_t<e>, A, B, C, D>{};


Demo with std::underlying_type_t

相关问题