如何在没有默认构造函数的情况下使用 std::transform 创建 std::array
How to create a std::array with std::transform without default constructor
我有一个 std::array<Foo, 10>
,我想使用从 Foo
到 Bar
的函数创建一个 std::array<Bar, 10>
。通常我会像这样使用 std::transform
:
array<Bar, 10> bars;
transform(foos.begin(), foos.end(), bars.begin(), [](Foo foo){
return Bar(foo.m_1, foo.m_2);
});
但是,Bar
没有默认构造函数,所以我无法创建 bars
数组。我总是可以使用 vector
但能够使用 array
来保证我总是恰好有 10 个元素会很好。这可能吗?
std::transform
没有,但没有什么是模板魔术无法解决的。
template<std::size_t N, std::size_t... Is>
std::array<Bar, N> foos_to_bars(const std::array<Foo, N>& foos,
std::index_sequence<Is...>) {
return {{ Bar(foos[Is].m_1, foos[Is].m_2)... }};
}
template<std::size_t N, std::size_t... Is>
std::array<Bar, N> foos_to_bars(const std::array<Foo, N>& foos) {
return foos_to_bars(foos, std::make_index_sequence<N>());
}
std::index_sequence
和朋友是 C++14,但很容易在 C++11 中实现。仅 SO 就可能有六种实现。
我有一个 std::array<Foo, 10>
,我想使用从 Foo
到 Bar
的函数创建一个 std::array<Bar, 10>
。通常我会像这样使用 std::transform
:
array<Bar, 10> bars;
transform(foos.begin(), foos.end(), bars.begin(), [](Foo foo){
return Bar(foo.m_1, foo.m_2);
});
但是,Bar
没有默认构造函数,所以我无法创建 bars
数组。我总是可以使用 vector
但能够使用 array
来保证我总是恰好有 10 个元素会很好。这可能吗?
std::transform
没有,但没有什么是模板魔术无法解决的。
template<std::size_t N, std::size_t... Is>
std::array<Bar, N> foos_to_bars(const std::array<Foo, N>& foos,
std::index_sequence<Is...>) {
return {{ Bar(foos[Is].m_1, foos[Is].m_2)... }};
}
template<std::size_t N, std::size_t... Is>
std::array<Bar, N> foos_to_bars(const std::array<Foo, N>& foos) {
return foos_to_bars(foos, std::make_index_sequence<N>());
}
std::index_sequence
和朋友是 C++14,但很容易在 C++11 中实现。仅 SO 就可能有六种实现。