这是向容器添加元素的正确方法吗?
Is this the correct way to add elements to a container?
自从我编写 C++ 以来已经有一段时间了,所以我想确认我这样做是正确的:
vector<Mat>
VideoHash::dct3d(vector<Mat> cube)
{
vector<Mat> dctPlanes;
for (int k = 0; k < TEMPORAL_DIM; ++k)
{
Mat spatial;
Mat freq;
cube[k].convertTo(spatial, CV_64F);
dct(spatial, freq);
dctPlanes.push_back(freq);
}
// Do other stuff here
}
我有一个矩阵向量作为函数的输入。对于向量中的每个矩阵,我转换为不同的数据类型(double),对转换结果进行 DCT,然后将 DCT 的结果存储在另一个向量中。
这看起来对吗?我对在 for 循环内创建的矩阵有疑问。它们将在循环退出后超出范围。分配给堆栈上这些矩阵的内存会发生什么变化?循环后该内存是否仍可访问(例如在 "do other stuff here" 部分)。
当您 push_back 将矩阵放入向量时,它会按值复制到向量分配的内存中。只要 dctPlanes 存在,其中的矩阵就仍然存在。您的临时对象(空间,频率)当然会在每次循环迭代时超出范围。
编辑:为了解决优化问题,您可能会考虑这样的事情:
VideoHash::dct3d(vector<Mat> & cube)
{
Mat spatial;
vector<Mat> dctPlanes;
dctPlanes.resize(TEMPORAL_DIM);
for (int k = 0; k < TEMPORAL_DIM; ++k)
{
cube[k].convertTo(spatial, CV_64F);
dct(spatial, dctPlanes[k]);
}
// Do other stuff here
}
它并不完美,因为理想情况下,您希望在调整向量大小时避免调用所有这些构造函数的成本 - 并且有一些解决方法 - 但与原始代码相比,这将为您带来可观的收益。
dctPlanes.push_back(freq)
会复制临时矩阵freq
到容器中。如果Mat
有一个正确的复制构造函数,你仍然可以通过容器访问数据。显然,freq
和 spatial
本身在每次迭代结束时被销毁,无法直接访问。
如果效率是一个问题,您可能需要考虑为 Mat 实现 C++11 移动构造函数,然后使用:
dctPlanes.push_back( std::move(freq) )
在这一行之后,freq
本身甚至在循环作用域结束之前就失效了 - 因为它已被 移动 到容器中。
自从我编写 C++ 以来已经有一段时间了,所以我想确认我这样做是正确的:
vector<Mat>
VideoHash::dct3d(vector<Mat> cube)
{
vector<Mat> dctPlanes;
for (int k = 0; k < TEMPORAL_DIM; ++k)
{
Mat spatial;
Mat freq;
cube[k].convertTo(spatial, CV_64F);
dct(spatial, freq);
dctPlanes.push_back(freq);
}
// Do other stuff here
}
我有一个矩阵向量作为函数的输入。对于向量中的每个矩阵,我转换为不同的数据类型(double),对转换结果进行 DCT,然后将 DCT 的结果存储在另一个向量中。
这看起来对吗?我对在 for 循环内创建的矩阵有疑问。它们将在循环退出后超出范围。分配给堆栈上这些矩阵的内存会发生什么变化?循环后该内存是否仍可访问(例如在 "do other stuff here" 部分)。
当您 push_back 将矩阵放入向量时,它会按值复制到向量分配的内存中。只要 dctPlanes 存在,其中的矩阵就仍然存在。您的临时对象(空间,频率)当然会在每次循环迭代时超出范围。
编辑:为了解决优化问题,您可能会考虑这样的事情:
VideoHash::dct3d(vector<Mat> & cube)
{
Mat spatial;
vector<Mat> dctPlanes;
dctPlanes.resize(TEMPORAL_DIM);
for (int k = 0; k < TEMPORAL_DIM; ++k)
{
cube[k].convertTo(spatial, CV_64F);
dct(spatial, dctPlanes[k]);
}
// Do other stuff here
}
它并不完美,因为理想情况下,您希望在调整向量大小时避免调用所有这些构造函数的成本 - 并且有一些解决方法 - 但与原始代码相比,这将为您带来可观的收益。
dctPlanes.push_back(freq)
会复制临时矩阵freq
到容器中。如果Mat
有一个正确的复制构造函数,你仍然可以通过容器访问数据。显然,freq
和 spatial
本身在每次迭代结束时被销毁,无法直接访问。
如果效率是一个问题,您可能需要考虑为 Mat 实现 C++11 移动构造函数,然后使用:
dctPlanes.push_back( std::move(freq) )
在这一行之后,freq
本身甚至在循环作用域结束之前就失效了 - 因为它已被 移动 到容器中。