在C ++中生成任意嵌套的向量
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在C ++中生成任意嵌套的向量相关的知识,希望对你有一定的参考价值。
我正在尝试编写一个函数,以生成任意嵌套的向量,并使用C ++中的给定特定值进行初始化。例如,期望auto test_vector = n_dim_vector_generator<2, long double>(static_cast<long double>(1), 1);
创建一个类型为std::vector<std::vector<long double>>
的“ test_vector”对象。该test_vector的内容应与以下代码相同。
std::vector<long double> vector1;
vector1.push_back(1);
std::vector<std::vector<long double>> test_vector;
test_vector.push_back(vector1);
n_dim_vector_generator函数的更复杂用法:
auto test_vector2 = n_dim_vector_generator<15, long double>(static_cast<long double>(2), 3);
在这种情况下,参数static_cast<long double>(2)
作为向量中的数据,数字3
作为推动时间。因此,此test_vector2的内容应与以下代码相同。
std::vector<long double> vector1;
vector1.push_back(static_cast<long double>(2));
vector1.push_back(static_cast<long double>(2));
vector1.push_back(static_cast<long double>(2));
std::vector<std::vector<long double>> vector2;
vector2.push_back(vector1);
vector2.push_back(vector1);
vector2.push_back(vector1);
std::vector<std::vector<std::vector<long double>>> vector3;
vector3.push_back(vector2);
vector3.push_back(vector2);
vector3.push_back(vector2);
//...Totally repeat 15 times in order to create test_vector2
std::vector<...std::vector<long double>> test_vector2;
test_vector2.push_back(vector14);
test_vector2.push_back(vector14);
test_vector2.push_back(vector14);
实现n_dim_vector_generator功能的细节如下。
#include <iostream>
#include <vector>
template <typename T, std::size_t N>
struct n_dim_vector_type;
template <typename T>
struct n_dim_vector_type<T, 0>
using type = T;
;
template <typename T, std::size_t N>
struct n_dim_vector_type
using type = std::vector<typename n_dim_vector_type<T, N - 1>::type>;
;
template<std::size_t N, typename T>
typename n_dim_vector_type<T,N>::type n_dim_vector_generator(T t, unsigned int);
template <std::size_t N, typename T>
typename n_dim_vector_type<T, N>::type n_dim_vector_generator<N, T>(T input_data, unsigned int push_back_times)
if (N == 0)
return std::move(input_data);
typename n_dim_vector_type<T, N>::type return_data;
for (size_t loop_number = 0; loop_number < push_back_times; loop_number++)
return_data.push_back(n_dim_vector_generator<N - 1, T>(input_data, push_back_times));
return return_data;
结果,我得到一个错误'return': cannot convert from 'long double' to 'std::vector<std::vector<long double,std::allocator<long double>>,std::allocator<std::vector<long double,std::allocator<long double>>>>'
,我知道它是由if (N == 0)
块引起的,这是递归结构的终止条件。但是,如果我尝试将终止条件编辑为单独的形式。
template <typename T>
inline T n_dim_vector_generator<0, T>(T input_data, unsigned int push_back_times)
return std::move(input_data);
template <std::size_t N, typename T>
typename n_dim_vector_type<T, N>::type n_dim_vector_generator<N, T>(T input_data, unsigned int push_back_times)
typename n_dim_vector_type<T, N>::type return_data;
for (size_t loop_number = 0; loop_number < push_back_times; loop_number++)
return_data.push_back(n_dim_vector_generator<N - 1, T>(input_data, push_back_times));
return return_data;
发生错误'n_dim_vector_generator': illegal use of explicit template arguments
。有没有更好的解决方案来解决这个问题?
开发环境是Windows 10 1909中的Microsoft Visual Studio Enterprise 2019版本16.4.3
要实现您的特定映射:
auto test_vector = n_dim_vector_generator<2, long double>(2, 3)
对于一个充满2的3x3向量,如果您利用此vector
构造函数,您的模板可能会更简单:
std::vector<std::vector<T>>(COUNT, std::vector<T>(...))
由于vector
是可复制的,这将用不同的向量副本填充COUNT个插槽。所以...
template <size_t N, typename T>
struct n_dim_vector_generator
using type = std::vector<typename n_dim_vector_generator<N-1, T>::type>;
type operator()(T value, size_t size)
return type(size, n_dim_vector_generator<N-1, T>(value, size));
;
template <typename T>
struct n_dim_vector_generator<0, T>
using type = T;
type operator()(T value, size_t size)
return value;
;
用法:
auto test_vector = n_dim_vector_generator<2, long double>(2, 3);
演示:https://godbolt.org/z/eiDAUG
为了记录起见,为了解决注释中的某些问题,C ++ has等效于多维C数组的惯用,可初始化,连续内存类:嵌套std::array
:]]
std::array<std::array<long double, COLUMNS>, ROWS> test_array = /*...*/ ; for (auto& row : test_array) for (auto cell : row) std::cout << cell << std::endl;
如果要减少样板声明一个,则可以使用一个结构:
template <typename T, size_t... N> struct multi_array; template <typename T, size_t NFirst, size_t... N> struct multi_array<T, NFirst, N...> using type = std::array<typename multi_array<T, N...>::type, NFirst>; ; template <typename T, size_t NLast> struct multi_array<T, NLast> using type = std::array<T, NLast>; ; template <typename T, size_t... N> using multi_array_t = typename multi_array<T, N...>::type;
然后使用:
multi_array_t<long double, ROWS, COLUMNS> test_array = /*...*/ ; for (auto& row : test_array) for (auto cell : row) std::cout << cell << std::endl;
这是像C数组一样分配在堆栈上的。当然,这会耗尽您的堆栈空间。但是您可以在
std::unique_ptr
周围设置装饰器范围,以使指向该装饰器的指针更容易访问:
template <typename T, size_t... N> struct dynamic_multi_array : std::unique_ptr<multi_array_t<T, N...>> using std::unique_ptr<multi_array_t<T, N...>>::unique_ptr; constexpr typename multi_array_t<T, N...>::value_type& operator [](size_t index) return (**this)[index]; constexpr const typename multi_array_t<T, N...>::value_type& operator [](size_t index) const return (**this)[index]; constexpr typename multi_array_t<T, N...>::iterator begin() return (**this).begin(); constexpr typename multi_array_t<T, N...>::iterator end() return (**this).end(); constexpr typename multi_array_t<T, N...>::const_iterator begin() const return (**this).begin(); constexpr typename multi_array_t<T, N...>::const_iterator end() const return (**this).end(); constexpr typename multi_array_t<T, N...>::const_iterator cbegin() const return (**this).cbegin(); constexpr typename multi_array_t<T, N...>::const_iterator cend() const return (**this).cend(); constexpr typename multi_array_t<T, N...>::size_type size() const return (**this).size(); constexpr bool empty() const return (**this).empty(); constexpr typename multi_array_t<T, N...>::value_type* data() return (**this).data(); constexpr const typename multi_array_t<T, N...>::value_type* data() const return (**this).data(); ;
(如果将这些方法与
nullptr
一起使用,请买家当心,
然后您仍然可以将new
表达式初始化为大括号并将其用作容器:
dynamic_multi_array<long double, ROWS, COLUMNS> test_array
new multi_array_t<long double, ROWS, COLUMNS> /* ... */
;
for (auto& row : test_array)
for (auto cell : row)
std::cout << cell << std::endl;
以上是关于在C ++中生成任意嵌套的向量的主要内容,如果未能解决你的问题,请参考以下文章