用较小的数组初始化C++std::数组
Initializing C++ std::array with smaller arrays
如何用几个较小的std::数组构造一个std::数组,而不是数组元素?
即:
std::array<std::string, 2> strings = { "a", "b" };
std::array<std::string, 2> more_strings = { "c", "d" };
std::string another_string = "e";
std::array<std::string, 5> result = {strings, more_strings, another_string};
同样的问题也适用于用较小的std::initializer_list初始化std::initializer_list。
如果可能的话,您可能会发现元组在最终创建数组之前更容易处理(也更高效)。
从概念上讲,你可以写这样的东西:
using namespace std;
auto strings = make_tuple( "a"s, "b"s );
auto more_strings = make_tuple( "c"s, "d"s);
auto another_string = make_tuple("e"s);
auto result = to_array(tuple_cat(strings, more_strings, another_string));
当然,您需要一个to_array的实现,这不是一个微不足道的实现。完整的代码如下,在这个答案中归功于Luc Danton:将std::tuple转换为std::array C++11
完整参考代码:
#include <iostream>
#include <string>
#include <tuple>
#include <array>
template<int... Indices>
struct indices {
using next = indices<Indices..., sizeof...(Indices)>;
};
template<int Size>
struct build_indices {
using type = typename build_indices<Size - 1>::type::next;
};
template<>
struct build_indices<0> {
using type = indices<>;
};
template<typename T>
using Bare = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
template<typename Tuple>
constexpr
typename build_indices<std::tuple_size<Bare<Tuple>>::value>::type
make_indices()
{ return {}; }
template<typename Tuple, int... Indices>
std::array<
typename std::tuple_element<0, Bare<Tuple>>::type,
std::tuple_size<Bare<Tuple>>::value
>
to_array(Tuple&& tuple, indices<Indices...>)
{
using std::get;
return {{ get<Indices>(std::forward<Tuple>(tuple))... }};
}
template<typename Tuple>
auto to_array(Tuple&& tuple)
-> decltype( to_array(std::declval<Tuple>(), make_indices<Tuple>()) )
{
return to_array(std::forward<Tuple>(tuple), make_indices<Tuple>());
}
auto main() -> int
{
using namespace std;
auto strings = make_tuple( "a"s, "b"s );
auto more_strings = make_tuple( "c"s, "d"s);
auto another_string = make_tuple("e"s);
auto result = to_array(tuple_cat(strings, more_strings, another_string));
for (const auto& e : result)
{
cout << e << endl;
}
return 0;
}
这里有一个可以加入std::array
s的函数。
template<typename T>
auto wrap_value(T&& value)
{
return std::tuple<T&&>(std::forward<T>(value));
}
template<typename T, std::size_t N>
std::array<T, N>& wrap_value(std::array<T, N>& value)
{
return value;
}
template<typename T, std::size_t N>
std::array<T, N> const& wrap_value(std::array<T, N> const& value)
{
return value;
}
template<typename T, std::size_t N>
std::array<T, N>&& wrap_value(std::array<T, N>&& value)
{
return std::move(value);
}
template<std::size_t... Is, typename... Ts>
std::array<std::common_type_t<Ts...>, sizeof...(Is)>
join_arrays_impl(std::index_sequence<Is...>, std::tuple<Ts...>&& parts)
{
return {std::get<Is>(std::move(parts))...};
}
template<typename... Ts>
auto join_arrays(Ts&&... parts)
{
auto wrapped_parts = std::tuple_cat((wrap_value)(std::forward<Ts>(parts))...);
constexpr auto size = std::tuple_size<decltype(wrapped_parts)>::value;
std::make_index_sequence<size> seq;
return (join_arrays_impl)(seq, std::move(wrapped_parts));
}
我认为您无法为std::initializer_list
s实现类似的功能。请参阅此处的工作原理。
相关文章:
- C++使用整数的压缩数组初始化对象
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 从另一个静态常量数组初始化静态常量数组(只需少量计算)
- 在 Python 和 c++ 2d 数组初始化之间.这是怎麽?为什么呢?
- 字节数组初始化会导致 DirectX 崩溃
- 使用 new 和 值进行数组初始化,但没有显式数量的元素
- 运行时C++数组初始化问题
- 使用带有参数包的数组的成员数组初始化类
- 仅通过C++中数组初始化的不同方法,即可在同一输入上获得两个不同的答案
- C++ 2 个指针数组初始化 C2440
- C++结构字符数组初始化
- C++中的多维数组初始化
- constexpr数组初始化
- C++引物动态数组初始化程序的数目超过大小
- 使用std::index_sequence对std::数组初始化进行包扩展
- 当 std 数组初始化太小时,C++会引发错误吗?
- 如何确定结构数组初始化的大小?
- Qt并发错误:数组初始化需要大括号括起来的初始值设定项列表
- 此代码中的数组初始化样式是什么?这是标准的吗?
- C++ 使用数组初始化时的 STL 向量内存管理