C++ 调整模板中递归嵌套向量的大小

C++ 调整模板中递归嵌套向量的大小,c++,templates,vector,C++,Templates,Vector,我正在尝试制作一个模板函数,它可以调整嵌套向量在所有维度上的大小 非常像这样:,但对于任意数量的DIM (我假设)该函数(至少)将接受对向量(或向量或v等)的引用和具有所需大小的向量。我现在在sizes向量中也有索引,但可能不需要 到目前为止,这是我最终得到的结果(可能是完全错误的): template void resize(vector&V1、vector t、int32\t索引){ int32\u t当前大小=t.at(索引); cout您可能正在寻找类似的解决方案(这是与c++14兼容的

我正在尝试制作一个模板函数,它可以调整嵌套向量在所有维度上的大小

非常像这样:,但对于任意数量的DIM

(我假设)该函数(至少)将接受对向量(或
向量
v
等)的引用和具有所需大小的向量。我现在在sizes向量中也有索引,但可能不需要

到目前为止,这是我最终得到的结果(可能是完全错误的):

template void resize(vector&V1、vector t、int32\t索引){
int32\u t当前大小=t.at(索引);

cout您可能正在寻找类似的解决方案(这是与c++14兼容的解决方案,类似的解决方案对于c++11可能会有点棘手,但仍然有可能):

#包括
#包括
#包括
模板
无效嵌套大小(std::vector&v、Tuple&t);
模板
无效嵌套大小(std::vector&v、Tuple&t);
模板
无效嵌套\u resize\u impl(向量&v、元组&t、标准::索引\u序列){
v、 调整大小(std::get(t));
用于(自动和nv:v){
嵌套的调整大小(nv,std::forward_作为元组(std::get(t)…);
}
}
模板
无效嵌套大小(std::vector&v、Tuple&t){
嵌套的_resize_impl(v,t,std::make_index_sequence{});
}
模板
无效嵌套大小(std::vector&v、Tuple&t){
v、 调整大小(std::get(t));
}
int main(){
向量矩阵;
嵌套调整大小(矩阵,std::make_元组(3,2,3));
matrix.at(2).at(1).at(2)=0;//at仅当元素存在时才提供访问权限,否则会引发异常
}
这项工作:

    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 void resizer(V&V1,vector const&t,int32_t index){}
模板无效大小调整器(向量&V1、向量常量&t、int32\t索引){
int32\u t当前大小=t.at(索引);
V1.调整大小(t.at(索引));
++指数;
如果(索引
但这实际上要好一点,因为我们没有不必要地迭代最后一个维度的元素:

    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);
            }
        }
    }
模板无效大小调整器(向量&V1、向量常量&t、int32\t索引){
int32\u t当前大小=t.at(索引);
V1.调整大小(t.at(索引));
}
模板无效大小调整器(向量&V1、向量常量&t、int32\t索引){
int32\u t当前大小=t.at(索引);
V1.调整大小(t.at(索引));
++指数;
如果(索引
这里真正的问题是,模板的每个实例都需要为两种可能性生成代码:多维向量的最后一个维度和向量的所有其他维度。对于后者,有必要在向量的以下维度上递归,这将导致明显的错误关于前者的错误

这需要专门化:

#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;
}
#包括
#包括
模板
类大小调整{
公众:
静态空间大小调整(V&V1,
iter_b型、iter_e型)
{
如果(b==e)
返回;
V1.调整大小(*b);
}
};
模板
类大小调整{
公众:
静态空间大小调整(标准::矢量和V1,
iter_b型、iter_e型)
{
如果(b==e)
返回;
V1.调整大小(*b);
++b;
for(typename std::vector::iterator)
vb=V1.begin(),
ve=V1.end();vb!=ve;++vb)
调整大小::调整大小(*vb,b,e);
}
};
模板
空心尺寸调整(V&V,常量标准::矢量和尺寸)
{
调整尺寸
::调整大小(v,dimensions.begin(),dimensions.end());
}
int main()
{
std::向量v;
std::载体d;
d、 推回(3);
d、 推回(3);
d、 推回(3);
调整大小(v,d);

std::cout向量中的“所有维度”是什么?Hayt:每个嵌套向量都有一个维度。所以向量,一个维度,向量两个维度,等等…@Wiebe你可以将你的代码作为一个备选答案发布(我不认为在问题中发布答案是一种好的方式)@好的,我会的。谢谢。它确实帮助修复了我代码中的一些细节,我让它工作了。你建议的代码是否更有效(或者更好)那么我发布的有效解决方案呢?@Wiebe很高兴听到:)@Wiebe除了给IMHO一个更麻烦的调用方式之外,我实际上认为您的解决方案会在同样的时间复杂度下工作谢谢。我必须弄清楚现在使用哪种解决方案,或者每个解决方案使用哪种过去。您是对的,这里有错误的空间,因此,在某个时候,可能最好创建一个类来嵌入dim、dim大小和嵌套向量的数量,在。。。
    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);
            }
        }
    }
#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;
}