在模板中调整递归嵌套向量的大小
Posted
技术标签:
【中文标题】在模板中调整递归嵌套向量的大小【英文标题】:Resize recursive nested vector in template 【发布时间】:2016-09-26 10:18:23 【问题描述】:我正在尝试制作一个模板函数来调整嵌套向量的所有维度。
很像这样:resizing multidimensional vector,但对于任意 nr。暗淡。
(我想)该函数将(至少)接受对向量(或vector<vector<T>>
或v<v<v<T>>>
等)的引用和具有所需大小的向量。我现在在尺寸向量中也有 in 索引,但可能不需要它。
到目前为止,这是我最终的结果(可能完全错误):
template<typename V> void resize(vector<V> & V1, vector<int32_t> t, int32_t index)
int32_t current_size=t.at(index);
cout << "resize dim [" << index << "] to size " << current_size <<endl ;
++index;
if (index < t.size())
// for each element ??
// for( int i = 0 ; i < V1.size(); i++ ) resize (V1.at(i), t, index); // doesn't work
// for( auto const& e : V1 ) resize (e, t, index); // doesn't work
// resize( V1, t, index); // recursive call, works, but doesn't do anything
我想避免复制 V1 或其任何内容。我不确定是否有一种方法可以使用迭代器或 for 循环来传递引用。如果没有,可能需要第四个输入来保持 V1 的索引?
顺便说一句,我故意跳过第一个暗淡,它已经是正确的大小。
任何帮助表示赞赏。
【问题讨论】:
什么是向量中的“所有维度”? Hayt:每个嵌套向量的一维。所以vector您可能正在寻找类似的东西(这是符合 c++14 的解决方案,类似的解决方案对于 c++11 会有点棘手,但仍然可能):
#include <vector>
#include <tuple>
#include <utility>
template <class NestedVectorElement, class Tuple>
void nested_resize(std::vector<std::vector<NestedVectorElement>> &v, Tuple &&t);
template <class VectorElement, class Tuple>
void nested_resize(std::vector<VectorElement> &v, Tuple &&t);
template <class Vector, class Tuple, size_t... Is>
void nested_resize_impl(Vector &v, Tuple &&t, std::index_sequence<Is...>)
v.resize(std::get<0>(t));
for(auto &nv: v)
nested_resize(nv, std::forward_as_tuple(std::get<Is + 1>(t)...));
template <class NestedVectorElement, class Tuple>
void nested_resize(std::vector<std::vector<NestedVectorElement>> &v, Tuple &&t)
nested_resize_impl(v, t, std::make_index_sequence<std::tuple_size<Tuple>::value - 1>);
template <class VectorElement, class Tuple>
void nested_resize(std::vector<VectorElement> &v, Tuple &&t)
v.resize(std::get<0>(t));
int main()
std::vector<std::vector<std::vector<int>>> matrix;
nested_resize(matrix, std::make_tuple(3, 2, 3));
matrix.at(2).at(1).at(2) = 0; // at gives you an access only if element exists else throws an exception
【讨论】:
谢谢。它确实帮助修复了我的代码中的一些细节,并且我得到了它的工作。 您建议的代码是否比我发布的工作解决方案更有效(或更好)? @Wiebe 很高兴听到它:) @Wiebe 除了恕我直言,调用方式有点繁琐,我实际上认为您的解决方案可以在相同的时间复杂度下工作【参考方案2】:这里真正的问题是模板的每个实例都需要为两种可能性生成代码:多维向量的最后一个维度,以及向量的所有其他维度。而在后者的情况下,需要对向量的以下维度进行递归,这在前者的情况下会导致明显的编译错误。
这需要专业化:
#include <vector>
#include <iostream>
template<typename V, typename iter_type>
class resize_dim
public:
static void resize(V & V1,
iter_type b, iter_type e)
if (b == e)
return;
V1.resize(*b);
;
template<typename V, typename iter_type>
class resize_dim<std::vector<std::vector<V>>, iter_type>
public:
static void resize(std::vector<std::vector<V>> & V1,
iter_type b, iter_type e)
if (b == e)
return;
V1.resize(*b);
++b;
for (typename std::vector<std::vector<V>>::iterator
vb=V1.begin(),
ve=V1.end(); vb != ve; ++vb)
resize_dim<std::vector<V>, iter_type>::resize(*vb, b, e);
;
template<typename V>
void resize(V &v, const std::vector<size_t> &dimensions)
resize_dim<V, std::vector<size_t>::const_iterator>
::resize(v, dimensions.begin(), dimensions.end());
int main()
std::vector<std::vector<std::vector<int>>> v;
std::vector<size_t> d;
d.push_back(3);
d.push_back(3);
d.push_back(3);
resize(v, d);
std::cout << "Ok" << std::endl;
return 0;
大小向量,给出每个维度的大小应该与向量中的维度数相匹配。多余的尺寸会被忽略。较小的尺寸只会导致前导尺寸被调整大小。
【讨论】:
谢谢。我必须弄清楚现在要使用哪种解决方案,或者每种解决方案的过去。你是对的,这里有错误的空间,所以在某些时候最好创建一个嵌入 nr 的类。暗淡、暗淡大小和嵌套向量,在...【参考方案3】:这行得通:
template<typename V> void resizer(V & V1, vector<int32_t> const & t, int32_t index)
template<typename V> void resizer(vector<V> & V1, vector<int32_t> const & t, int32_t index)
int32_t current_size=t.at(index);
V1.resize(t.at(index) );
++index;
if (index < t.size() )
for( auto & e : V1 )
resizer (e , t, index);
但这实际上要好一些,因为我们没有不必要地迭代最后一个维度的元素:
template<typename V> void resizer(vector<V> & V1, vector<int32_t> const & t, int32_t index)
int32_t current_size=t.at(index);
V1.resize(t.at(index) );
template<typename V> void resizer(vector<std::vector<V>> & V1, vector<int32_t> const & t, int32_t index)
int32_t current_size=t.at(index);
V1.resize(t.at(index) );
++index;
if (index < t.size() )
for( auto & e : V1 )
resizer (e , t, index);
【讨论】:
以上是关于在模板中调整递归嵌套向量的大小的主要内容,如果未能解决你的问题,请参考以下文章