我试图制作一个模板函数来调整嵌套向量的所有维度。
非常像这样:resizing multidimensional vector,但对于任意的nr。昏暗的。
(我想)该函数将(至少)接受对向量(或vector<vector<T>>
或v<v<v<T>>>
等)的引用以及具有所需大小的向量。我现在也在尺寸矢量中有索引,但可能不需要它。
到目前为止,这是我最终得到的结果(可能是完全错误的):
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或其任何内容。我不确定是否有一种方法可以使用迭代器或传递引用的循环。如果没有,可能需要进行第四次输入以保持V1的索引?
顺便说一句,我是故意跳过第一个昏暗的,它已经是正确的尺寸。
任何帮助表示感谢。
答案 0 :(得分:1)
你可能正在寻找类似这样的东西(这是符合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
}
答案 1 :(得分:1)
这有效:
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);
}
}
}
答案 2 :(得分:1)
这里真正的问题是模板的每个实例都需要为两种可能性生成代码:多维向量的最后一个维度,以及向量的所有其他维度。在后者的情况下,有必要对向量的以下维度进行递归,这将导致在前者的情况下出现明显的编译错误。
这需要专业化:
#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;
}
大小调整向量,给出每个维度的大小应该与向量中的维度数量相匹配。额外的尺寸被忽略。较小的尺寸只会导致尺寸调整的尺寸。