Dan*_*nra 20 c++ arrays templates c++11 c++14
如何构造一个std::array
索引序列,或一个依赖于顺序索引的lambda?
std::iota
并且std::generate
看起来很相关,但我不确定如何使用它们来构造一个std::array
,而不是将它们应用于已构造的一个(如果数组的元素类型不是默认构造的话,这是不可能的).
我要干的代码类型示例:
#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;
}
Run Code Online (Sandbox Code Playgroud)
Edg*_*jān 14
下一个方法应该适合你:
template<typename T, std::size_t N, std::size_t... I>
constexpr auto create_array_impl(std::index_sequence<I...>) {
return std::array<T, N>{ {I...} };
}
template<typename T, std::size_t N>
constexpr auto create_array() {
return create_array_impl<T, N>(std::make_index_sequence<N>{});
}
Run Code Online (Sandbox Code Playgroud)
您可以创建一个数组,如:
constexpr auto array = create_array<std::size_t, 4>();
Run Code Online (Sandbox Code Playgroud)
可以修改前面提到的解决方案,以便以下一种方式添加lambda:
template<typename T, std::size_t N, typename F, std::size_t... I>
constexpr auto create_array_impl(F&& func, std::index_sequence<I...>) {
return std::array<T, N>{ {func(I)...} };
}
template<typename T, std::size_t N, typename F>
constexpr auto create_array(F&& func) {
return create_array_impl<T, N>(std::forward<F>(func), std::make_index_sequence<N>{});
}
Run Code Online (Sandbox Code Playgroud)
然后使用:
const auto array = create_array<std::size_t, 4>([](auto e) {
return e * e;
});
Run Code Online (Sandbox Code Playgroud)
ild*_*arn 13
对于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);
Run Code Online (Sandbox Code Playgroud)
对于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}; });
Run Code Online (Sandbox Code Playgroud)
(noexcept
在这里IMO或多或少是可选的,为了简洁起见,这里省略了,但是在演示中存在.)
Nb都是完全的constexpr
,但由于generate_array
很可能与lambdas一起使用,因此constexpr
在 C++ 17(演示版)之前不会实践.generate_array
由于有保证的复制省略(演示),nb 也适用于C++ 17中的不可复制/不可移动类型.
归档时间: |
|
查看次数: |
2717 次 |
最近记录: |