我想知道是否有一种方法可以将std::array
转换为索引序列吗?
constexpr std::array<int, 5> x = {0, 3, 4, 5, 8};
constexpr auto integer_sequence = ...; // something that lead to integer_sequence<int, 0, 3, 4, 5, 8>;
我知道不可能使用一个函数,因为它将导致另一种类型。 但是,由于可以执行以下操作:
constexpr std::size_t x = 8;
std::integral_constant<int, x> height;
有可能以简单的方式做到吗?
我尝试执行以下操作:
#include <array>
#include <tuple>
template<std::size_t N>
constexpr std::array<int, N> m_iota(int value) {
std::array<int, N> result{};
for(auto &v : result)
v = value++;
return result;
}
template<int N>
using Int = std::integral_constant<int, N>;
int main() {
constexpr auto array = m_iota<5>(3); // 3, 4, 5, 6, 7
constexpr auto indexer = std::tuple<Int<0>,Int<1>,Int<2>,Int<3>,Int<4>>{};
auto to_sequence = [array](auto ...is) {return std::integer_sequence<int, array[is]...>{};};
auto x = std::apply(to_sequence, indexer);
static_assert(std::is_same_v<decltype(x), std::integer_sequence<int, 3, 4, 5, 6, 7>>);
}
它可以在GCC和clang上很好地编译,但是在MSVC中却不能...有没有更简单的方法?
以下是指向msvc的链接:https://godbolt.org/z/EK7azW
答案 0 :(得分:2)
(在C ++ 17中)std::array<T>
不能是模板参数类型,而const std::array<T>&
可以是模板参数类型。因此,在有问题的阵列具有静态存储持续时间的限制下,您可以编写
#include<array>
#include<utility>
#include<type_traits>
#include<cstddef>
template<const auto &A,
class=std::make_index_sequence<
std::tuple_size<std::decay_t<decltype(A)>>::value>>
struct as_sequence;
template<const auto &A,std::size_t ...II>
struct as_sequence<A,std::index_sequence<II...>> {
using type=std::integer_sequence<
typename std::decay_t<decltype(A)>::value_type,A[II]...>;
};
constexpr std::array<int, 5> x = {0, 3, 4, 5, 8};
static_assert(std::is_same_v<as_sequence<x>::type,
std::integer_sequence<int, 0, 3, 4, 5, 8>>);
答案 1 :(得分:1)
您可以尝试以下方法:
constexpr std::array<int, 5> x = {0, 3, 4, 5, 8};
template <int prepender, typename sequence>
struct prepend_integer_to_sequence {};
template <int prepender, int... sequence_nums>
struct prepend_integer_to_sequence<prepender, std::integer_sequence<int, sequence_nums...> > {
using type = std::integer_sequence<int, prepender, sequence_nums...>;
};
template <int prepender, typename sequence>
using prepend_integer_to_sequence_t = typename prepend_integer_to_sequence<prepender, sequence>::type;
template <size_t begin>
struct convert_array {
using type = prepend_integer_to_sequence_t<
x[begin],
typename convert_array<begin + 1>::type
>;
};
template <>
struct convert_array<x.size()> {
using type = std::integer_sequence<int>;
};
using int_seq = typename convert_array<0>::type;