C++ 当对象较大时,返回指针或值

C++ 当对象较大时,返回指针或值,c++,matrix,constexpr,C++,Matrix,Constexpr,假设我们创建一个矩阵类,它将nxm整数存储在成员变量std::array inner中。现在有两种方法可以添加: 方法1)按值返回(constexpr是可能的) 我的程序需要对1000x1000矩阵(图像)进行算术运算,因此使用方法1我立即得到堆栈溢出。我的程序还可以处理需要在编译时计算的小型4x4矩阵(量子计算中的密度矩阵),因此在这些constepr初始化中不可能使用方法2 问题:是否需要为每个返回矩阵的方法制作两个版本?(一个返回一个矩阵,另一个返回一个矩阵*)这将是大量重复的代码。这个问

假设我们创建一个
矩阵
类,它将nxm整数存储在成员变量
std::array inner中。现在有两种方法可以添加:

方法1)按值返回(
constexpr
是可能的)

我的程序需要对
1000x1000
矩阵(图像)进行算术运算,因此使用方法1我立即得到堆栈溢出。我的程序还可以处理需要在编译时计算的小型
4x4
矩阵(量子计算中的密度矩阵),因此在这些
constepr
初始化中不可能使用方法2

问题:是否需要为每个返回矩阵的方法制作两个版本?(一个返回一个
矩阵
,另一个返回一个
矩阵*
)这将是大量重复的代码。这个问题有多普遍?是否有另一种使用堆的方法,以便从
constexpr
也可以使用方法2

提到移动语义已将首选项稍微转移到方法1。但由此产生的堆栈溢出又如何呢

我的主张:

template<size_t n, size_t m>
class Matrix
{
public:
    Matrix& operator+=(const Matrix& other)
    {
        return *this;
    }
};

template<size_t n, size_t m>
Matrix<n, m> constexpr operator+(Matrix<n, m> x, Matrix<n, m> const& y)
{
    x += y;
    return x;
}

template<size_t n, size_t m>
std::unique_ptr<Matrix<n, m>> add(Matrix<n, m> const* x, Matrix<n, m> const* y)
{
    auto result = std::make_unique<n, m>(*x);
    *result += *y;
    return std::unique_result;
}
模板
类矩阵
{
公众:
矩阵和运算符+=(常数矩阵和其他)
{
归还*这个;
}
};
样板
矩阵constepr运算符+(矩阵x,矩阵const&y)
{
x+=y;
返回x;
}
样板
std::unique_ptr add(矩阵常数*x,矩阵常数*y)
{
自动结果=标准::使_唯一(*x);
*结果+=*y;
返回std::唯一的_结果;
}
现在,您可以对小矩阵使用按值加法:

Matrix<10, 12> m1, m2;
auto m3 = m1 + m2;
矩阵m1,m2;
自动m3=m1+m2;
以及可以动态分配的大型矩阵:

auto pm1 = std::make_unique<Matrix<12, 10>>();
auto pm2 = std::make_unique<Matrix<12, 10>>();
auto pm3 = add(pm1.get(), pm2.get());
auto pm1=std::make_unique();
自动pm2=std::使_唯一();
auto pm3=add(pm1.get(),pm2.get());
甚至:

auto pm3 = std::make_unique<Matrix<12, 10>>(pm1);
*pm3 += *pm2;
auto pm3=std::使_唯一(pm1);
*pm3+=*pm2;
我的建议:

template<size_t n, size_t m>
class Matrix
{
public:
    Matrix& operator+=(const Matrix& other)
    {
        return *this;
    }
};

template<size_t n, size_t m>
Matrix<n, m> constexpr operator+(Matrix<n, m> x, Matrix<n, m> const& y)
{
    x += y;
    return x;
}

template<size_t n, size_t m>
std::unique_ptr<Matrix<n, m>> add(Matrix<n, m> const* x, Matrix<n, m> const* y)
{
    auto result = std::make_unique<n, m>(*x);
    *result += *y;
    return std::unique_result;
}
模板
类矩阵
{
公众:
矩阵和运算符+=(常数矩阵和其他)
{
归还*这个;
}
};
样板
矩阵constepr运算符+(矩阵x,矩阵const&y)
{
x+=y;
返回x;
}
样板
std::unique_ptr add(矩阵常数*x,矩阵常数*y)
{
自动结果=标准::使_唯一(*x);
*结果+=*y;
返回std::唯一的_结果;
}
现在,您可以对小矩阵使用按值加法:

Matrix<10, 12> m1, m2;
auto m3 = m1 + m2;
矩阵m1,m2;
自动m3=m1+m2;
以及可以动态分配的大型矩阵:

auto pm1 = std::make_unique<Matrix<12, 10>>();
auto pm2 = std::make_unique<Matrix<12, 10>>();
auto pm3 = add(pm1.get(), pm2.get());
auto pm1=std::make_unique();
自动pm2=std::使_唯一();
auto pm3=add(pm1.get(),pm2.get());
甚至:

auto pm3 = std::make_unique<Matrix<12, 10>>(pm1);
*pm3 += *pm2;
auto pm3=std::使_唯一(pm1);
*pm3+=*pm2;

不要使用
std::array
,使用适当大小的
std::vector
。不幸的是,这是不可能的。我确实调用了一个外部dll(数学内核库),它希望矩阵像
std::array
那样存储。实际导致超链接的部分不在您发布的代码中。如果<代码>矩阵< /C>管理动态内存,不需要动态分配<代码>矩阵<代码>。如果你是英特尔的MKL,它在C接口中使用一维数组,没有C++接口。只有1000×1000?如果没有太多线程,或者正在使用64位二进制文件,请增加堆栈大小。不要使用
std::array
,请使用大小适当的
std::vector
。不幸的是,这是不可能的。我确实调用了一个外部dll(数学内核库),它希望矩阵像
std::array
那样存储。实际导致超链接的部分不在您发布的代码中。如果<代码>矩阵< /C>管理动态内存,不需要动态分配<代码>矩阵<代码>。如果你是英特尔的MKL,它在C接口中使用一维数组,没有C++接口。只有1000×1000?如果没有太多线程,或者使用64位二进制文件,只需增加堆栈大小即可。我想您忘记了在
操作符+=
中实际添加的内容。至少可以放一个占位符注释。@FrançoisAndrieux它在类中。。。我承认,我没有在里面添加任何内容,只是为了演示而已。我想你忘记了在
操作符+=
中实际添加的内容。至少可以放一个占位符注释。@FrançoisAndrieux它在类中。。。我承认,我没有在里面添加任何内容,但为了演示,应该已经足够了。