在 C++ 中传递和返回未知大小的二维数组

Passing and Returning a 2D array of unknown size in C++

我想传递 return 一个未知大小的二维数组,但我不知道该怎么做。我只知道 return 未知大小的数组(指针数组)。我知道如何传递未知大小的数组(模板),但同时传递和 returning 未知大小的二维数组对我来说不起作用。我有以下代码

template<typename Value_t, size_t FirstDim, size_t SecondDim> 
int** FooTakes2D_ArrayRef_to_Print(Value_t (&array2d)[FirstDim][SecondDim]) 
{ 
    for(size_t i=0; i<FirstDim; ++i) 
    { 
        for(size_t j=0; j<SecondDim; ++j) 
        { 
            std::cout<<array2d[i][j]<<' '; 
        } 
        std::cout<<"\n"; 
    } 
 
 return array2d; 
} 
 
int main() 

{ 
   
    double arr_d[][3]= { {1,2,3},  {4,5,6} }; 
    int** arr=FooTakes2D_ArrayRef_to_Print(arr_d);

 
return 0; 

}

对于初学者,您声明了一个双精度数组:

double arr_d[][3]= { {1,2,3},  {4,5,6} }; 

但随后在 the 函数声明和此语句中使用说明符 int

int** arr=FooTakes2D_ArrayRef_to_Print(arr_d);

请注意,在极少数情况下,表达式中使用的数组指示符会隐式转换为指向其第一个元素的指针。因此,例如数组 arr_d 可以隐式转换为类型 double ( * )[3].

的指针

函数可以如下所示:

template<typename Value_t, size_t FirstDim, size_t SecondDim> 
Value_t ( & FooTakes2D_ArrayRef_to_Print(Value_t (&array2d)[FirstDim][SecondDim]) )[FirstDim][SecondDim]
{ 
    for(size_t i=0; i<FirstDim; ++i) 
    { 
        for(size_t j=0; j<SecondDim; ++j) 
        { 
            std::cout<<array2d[i][j]<<' '; 
        } 
        std::cout<<"\n"; 
    } 
 
 return array2d; 
}

也就是说它可以return对源数组的引用。

或者喜欢例如

template<typename Value_t, size_t FirstDim, size_t SecondDim> 
Value_t ( * FooTakes2D_ArrayRef_to_Print(Value_t (&array2d)[FirstDim][SecondDim]) )[SecondDim]
{ 
    for(size_t i=0; i<FirstDim; ++i) 
    { 
        for(size_t j=0; j<SecondDim; ++j) 
        { 
            std::cout<<array2d[i][j]<<' '; 
        } 
        std::cout<<"\n"; 
    } 
 
 return array2d; 
}

return指向数组第一个元素的指针。

在这两种情况下,您都可以在 main 中声明一个指针,例如

double (* arr )[3] = FooTakes2D_ArrayRef_to_Print(arr_d);

这是一个演示程序

#include <iostream>

template<typename Value_t, size_t FirstDim, size_t SecondDim> 
Value_t ( & FooTakes2D_ArrayRef_to_Print(Value_t (&array2d)[FirstDim][SecondDim]) )[FirstDim][SecondDim]
{ 
    for(size_t i=0; i<FirstDim; ++i) 
    { 
        for(size_t j=0; j<SecondDim; ++j) 
        { 
            std::cout<<array2d[i][j]<<' '; 
        } 
        std::cout<<"\n"; 
    } 
 
 return array2d; 
}

template<typename Value_t, size_t FirstDim, size_t SecondDim> 
Value_t ( * FooTakes2D_ArrayRef_to_Print2(Value_t (&array2d)[FirstDim][SecondDim]) )[SecondDim]
{ 
    for(size_t i=0; i<FirstDim; ++i) 
    { 
        for(size_t j=0; j<SecondDim; ++j) 
        { 
            std::cout<<array2d[i][j]<<' '; 
        } 
        std::cout<<"\n"; 
    } 
 
 return array2d; 
}

int main()
{
    double arr_d[][3]= { {1,2,3},  {4,5,6} }; 
    double (* arr )[3] = FooTakes2D_ArrayRef_to_Print(arr_d);
    double (* arr2 )[3] = FooTakes2D_ArrayRef_to_Print2(arr_d);
}`

程序输出为:

1 2 3 
4 5 6 
1 2 3 
4 5 6 `

或者您可以通过以下方式为 two-dimensional 数组的引用使用别名:

#include <iostream>

template<typename Value_t, size_t FirstDim, size_t SecondDim> 
using Arr2D = Value_t ( & )[FirstDim][SecondDim];

template<typename Value_t, size_t FirstDim, size_t SecondDim> 
Arr2D<Value_t, FirstDim, SecondDim>
FooTakes2D_ArrayRef_to_Print(Arr2D<Value_t, FirstDim, SecondDim> array2d )
{ 
    for(size_t i=0; i<FirstDim; ++i) 
    { 
        for(size_t j=0; j<SecondDim; ++j) 
        { 
            std::cout<<array2d[i][j]<<' '; 
        } 
        std::cout<<"\n"; 
    } 
 
 return array2d; 
}

template<typename Value_t, size_t FirstDim, size_t SecondDim> 
auto FooTakes2D_ArrayRef_to_Print2(Arr2D<Value_t, FirstDim, SecondDim> array2d )
{ 
    for(size_t i=0; i<FirstDim; ++i) 
    { 
        for(size_t j=0; j<SecondDim; ++j) 
        { 
            std::cout<<array2d[i][j]<<' '; 
        } 
        std::cout<<"\n"; 
    } 
 
 return array2d; 
}

int main()
{
    double arr_d[][3]= { {1,2,3},  {4,5,6} }; 
    double (* arr )[3] = FooTakes2D_ArrayRef_to_Print(arr_d);
    double (* arr2 )[3] = FooTakes2D_ArrayRef_to_Print2(arr_d);
}

问题 是你函数的 return 类型是 int** 但你正在 returning array2d由于类型衰减衰减double (*)[3]。因此,函数的指定 return 类型与您实际 returning 的类型不匹配。

解决,您可以使用std::vector或使用占位符类型 auto,如下所示:

template<typename Value_t, size_t FirstDim, size_t SecondDim> 
//auto used here
auto FooTakes2D_ArrayRef_to_Print(Value_t (&array2d)[FirstDim][SecondDim]) -> decltype(array2d)
{ 
    for(size_t i=0; i<FirstDim; ++i) 
    { 
        for(size_t j=0; j<SecondDim; ++j) 
        { 
            std::cout<<array2d[i][j]<<' '; 
        } 
        std::cout<<"\n"; 
    } 
 
 return array2d; 
}
int main() 
{ 
   
    double arr_d[][3]= { {1,2,3},  {4,5,6} }; 
    //auto used here
    auto arr=FooTakes2D_ArrayRef_to_Print(arr_d);
}

Working demo