向函数传递智能指针

Passing smart pointers to a function

本文关键字:智能 指针 函数      更新时间:2023-10-16

我有一个双精度的二维智能指针数组。我可以为它赋值并显示它,但我在将它传递给以双**作为输入的函数时遇到了问题。简单的get()不起作用。

#include <iostream>
#include <memory>
using namespace std;
# define DIM1 3
# define DIM2 4
void funcCall(double** item)
{
    cout<< "Test function.";
}
int main() {
    std::unique_ptr<std::unique_ptr<double[]>> myArray(new std::unique_ptr<double[]>[DIM1]);
    for (int i = 0; i < DIM1; i++)
    {
        myArray.get()[i].reset(new double[DIM2]);
    }
    std::cout<<"Assign values"<<std::endl;
    for (int i = 0; i < DIM2; i++)
    {
        for (int j = 0; j < DIM1; j++)
        {
            myArray.get()[j][i] = (j+1)*(i+1);
        }
    }
    funcCall(myArray.get());    
    return 0;
}

当我编译这个时,我得到:

error: cannot convert 'std::unique_ptr<std::unique_ptr<double []> >::pointer {aka std::unique_ptr<double []>*}' to 'double**' for argument '1' to 'void funcCall(double**)'  funcCall(myArray.get())
void funcCall(std::unique_ptr<std::unique_ptr<double[]>> & arr)

应该做你想做的事,但是。。。

但是

听起来你想重新发明轮子。不要那样做。除非这是为了一项任务或个人教育,否则就疯了。

相反,请使用其中一个内置容器。

因为DIM1DIM2是常数,所以可以使用

std::array<std::array<double, DIM2>,DIM1> myArray;

void funcCall(std::array<std::array<double, DIM2>,DIM1> arr)

但如果你想要一个动态的解决方案,可能性是相当大的。在这种情况下,请尝试

std::vector<std::vector<double>> myArray(DIM1, std::vector<double>(DIM2));

void funcCall(std::vector<std::vector<double>> arr)

但是

老实说,这是一个愚蠢的赌注。阵列阵列或矢量矢量在内存中不连续,因此计算机必须在存储中跳跃,在不必要的缓存未命中上浪费时间,并且加载和可能重新加载缓存所花费的时间通常比所涉及的计算更长。在这一点上,世界上所有的133t数学都无法帮助你,因为你已经被IO门控了,而IO就是sssssssslllloooowwwwwwwwww。

你真正想要的是一个很好的一维数组,它是手动索引的。行*列数+列。当然,手动索引看起来像是额外的工作,但停下来想想:编译器在后台做了多少数学运算才能让数组工作,嗯?可能差不多。你就是看不到它。

让我们暂时使用std::vector,但这同样适用于std::array,甚至是一个好的ol'静态数组或智能指针内的动态数组。

std::vector<double> myArray(DIM1*DIM2);

使用这个相对简单:

myArray[row*DIM2 + column];

功能是:

void funcCall(std::vector<double> arr)

但这很容易封装在一个类中,并进一步简化:

class matrix
{
private: 
    std::vector<double> myArray;
    size_t nrRows;
    size_t nrColumns;
public:
    matrix(size_t rows, size_t columns): 
        myArray(rows*columns), nrRows(rows), nrColumns(columns)
    {
    }
    double& operator()(size_t row, size_t column)
    {
        return myArray[row* nrColumns + column];
    }
    double operator()(size_t row, size_t column) const
    {
        return myArray[row* nrColumns + column];
    }
};

结构:

matrix mat(DIM1, DIM2);

和用法:

double d = mat(1,2);

mat(2,1) = 3.14;

调用的类型和函数头不匹配。不能将unique_ptr视为常规指针。

一个解决方案是将您的函数定义更改为:

void funcCall(std::unique_ptr<double[]> *item)