如何构造具有索引序列的std :: array? [英] How to construct an std::array with index sequence?
问题描述
如何构造具有索引序列的std::array
或依赖于顺序索引的lambda?
How can I construct an std::array
with an index sequence, or a lambda which depends on a sequential index?
std::iota
和std::generate
似乎相关,但是我不确定如何使用它们来构造std::array
,而是将它们应用于已构造的对象(如果元素数组的类型不是默认可构造的.
std::iota
and std::generate
seem relevant, but I'm not sure how to use them to construct an std::array
, rather then apply them on one which is already constructed (which isn't possible in case the element type of the array isn't default-constructible).
示例我想要干燥的代码类型:
Example of the kind of code I'd like to DRY:
#include <array>
class C
{
public:
C(int x, float f) : m_x{x}, m_f{f} {}
private:
int m_x;
float m_f;
};
int main()
{
std::array<int, 10> ar = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::array<C, 3> ar2 = {C{0, 1.0}, C{1, 1.0}, C{2, 1.0}};
return 0;
}
推荐答案
对于ar
,这是一种方法:
namespace detail {
template<typename T, T... Ns>
constexpr auto make_iota_array(T const offset, std::integer_sequence<T, Ns...>) noexcept
-> std::array<T, sizeof...(Ns)> {
return {{(Ns + offset)...}};
}
}
template<typename T, T N>
constexpr auto make_iota_array(T const offset = {}) noexcept {
static_assert(N >= T{}, "no negative sizes");
return detail::make_iota_array<T>(offset, std::make_integer_sequence<T, N>{});
}
// ...
auto ar = make_iota_array<int, 10>(99);
对于ar2
,这是一种方法:
namespace detail {
template<typename T, typename F, std::size_t... Is>
constexpr auto generate_array(F& f, std::index_sequence<Is...>)
-> std::array<T, sizeof...(Is)> {
return {{f(std::integral_constant<std::size_t, Is>{})...}};
}
}
template<typename T, std::size_t N, typename F>
constexpr auto generate_array(F f) {
return detail::generate_array<T>(f, std::make_index_sequence<N>{});
}
// ...
auto ar2 = generate_array<C, 3>([](auto i) -> C { return {i, i * 1.12f}; });
(noexcept
在IMO中或多或少是可选的,为简洁起见,在此省略,但在演示中存在.)
(noexcept
is more-or-less optional here IMO, and omitted here for brevity, but is present in the demos.)
两者都完全是constexpr
,但是由于generate_array
可能与lambda一起使用,因此在C ++ 17之前,它不会在实践中成为constexpr
(有保证的复制省略(演示).
N.b. both are fully constexpr
, but since generate_array
is likely to be used with lambdas it won't be constexpr
in practice until C++17 (demo). Also n.b. generate_array
will work with non-copyable/non-movable types in C++17 due to guaranteed copy elision (demo).
这篇关于如何构造具有索引序列的std :: array?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!