2016-09-26 64 views
1

我试图制作一个模板函数,它在所有维度中调整嵌套向量的大小。在模板中调整递归嵌套向量的大小

非常像这样: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

什么是矢量中的“所有维度”? – Hayt

+0

Hayt:每个嵌套向量的一个维度。所以矢量,一个昏暗,矢量>两个昏暗等。 – Wiebe

+0

@Wiebe你可以发布你的代码作为替代答案(我不认为这是一个很好的方式在SO上发布问题的答案) –

回答

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 
} 
+0

谢谢。它确实帮助解决了我的代码中的一些细节,并且我得到了它的工作。 – Wiebe

+0

您推荐的代码是否更高效(或者更好),然后我发布的工作解决方案? – Wiebe

+0

@Wiebe很高兴听到:) –

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); 
      } 
     } 
    } 
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; 
} 

上浆向量,给每个维度的大小应与在向量的维数。额外的大小被忽略。只有在领先的尺寸得到调整后才能获得更少的尺寸。

+0

谢谢。我将不得不找出现在使用哪种解决方案,或每种解决方案的哪个解决方案。你是对的,这里有错误的空间,所以在某个时候,最好是让一个班级嵌入nr。暗淡,昏暗的大小和嵌套向量,在... – Wiebe