在 class 的初始化列表中初始化 std::vector
Initialize std::vector in class's initializer list
我不确定我是否应该在 Whosebug 或 CodeReview 上问这个问题。但是因为我找不到类似的问题,所以我把它贴在这里。
ATM 我正在优化一个简单的图像处理应用程序的代码。
其中一个目标就是把所有的卷积效果classes各自的矩阵作为自己的私有变量。因为 const-correctness 这并没有早点完成,但是解决引入的 const-correctness 问题的快速修复并不少于内存和 cpu-cycles。
所以我决定在 class-initialization-level 初始化卷积矩阵 std::vector<std::vector<double>>
因为创建数十个构造函数以使每个 std::array<std::array<double>,\d+>,\d+>
的初始化成为可能,效率低下。
BlurFilter::BlurFilter() : ColorEffect(), convolutionMatrix(
std::vector<std::vector<double>>{
std::vector<double>{ 0.0, 0.0, 1.0, 0.0, 0.0 },
std::vector<double>{ 0.0, 1.0, 1.0, 1.0, 0.0 },
std::vector<double>{ 1.0, 1.0, 1.0, 1.0, 1.0 },
std::vector<double>{ 0.0, 1.0, 1.0, 1.0, 0.0 },
std::vector<double>{ 0.0, 0.0, 1.0, 0.0, 0.0 }
} )
{
}
不过。应用程序在 Matrix 构造函数中运行时中断,出现 std::out_of_range
异常,what() 消息:
what(): vector::_M_range_check: __n (which is 0) >= this->size() (which is 0)"
又名 multidimensionalVector.size() 是 0.
Matrix::Matrix( const std::vector<std::vector<double>>& multidimensionalVector )
{
this->xLength = multidimensionalVector.size();
this->yLength = ( *multidimensionalVector.begin() ).size();
this->values = multidimensionalVector;
}
老实说,我不明白为什么 multidimentionalVector 的大小在那一刻根本为零,因为我正在传递一个初始化的向量向量,它可以是 - 如图所示 - 复制构造(或移动构造)转到矩阵 class 的值变量。更改 multidimensionalVector 按值复制不会有什么不同。
有人可以解释一下 and/or 这里出了什么问题吗?
(PS:我更喜欢用自己的话(也就是简单的英语)写的答案,而不是直接引用 C++ 标准文档,因为使用了模糊和令人困惑的 academic/scientific 语言) .
FWIW,您可以大大简化您的代码。这是一个有效的例子:
#include <iostream>
#include <vector>
struct Matrix
{
Matrix(const std::vector<std::vector<double>>& multidimensionalVector);
size_t xLength;
size_t yLength;
std::vector<std::vector<double>> values;
};
Matrix::Matrix( const std::vector<std::vector<double>>& multidimensionalVector ) : xLength(0), yLength(0), values(multidimensionalVector)
{
this->xLength = values.size();
std::cout << "xLength: " << xLength << std::endl;
if ( xLength > 0 )
{
this->yLength = ( *values.begin() ).size();;
}
std::cout << "yLength: " << yLength << std::endl;
}
struct BlurFilter
{
BlurFilter();
Matrix convolutionMatrix;
};
BlurFilter::BlurFilter() : convolutionMatrix( { { 0.0, 0.0, 1.0, 0.0, 0.0 },
{ 0.0, 1.0, 1.0, 1.0, 0.0 },
{ 1.0, 1.0, 1.0, 1.0, 1.0 },
{ 0.0, 1.0, 1.0, 1.0, 0.0 },
{ 0.0, 0.0, 1.0, 0.0, 0.0 } } )
{
}
int main()
{
BlurFilter f;
}
嗯,这让我很尴尬。
看来我在剥离和优化发布此问题的代码时无意中解决了自己的问题。在发布之前,我没有想过尝试简化代码。
放
this->values = multidimensionalVector;
完成任务。
似乎引发 std::out_of_range
异常的 Matrix-constructor 的原文是这样的:
Matrix::Matrix( const std::vector<std::vector<double>>& multidimensionalVector )
{
this->xLength = multidimensionalVector.size();
this->yLength = ( *multidimensionalVector.begin() ).size();
for( int x = 0; x < this->xLength; x++ )
{
for( int y = 0; y < this->yLength; y++ )
{
this->set( x, y, multidimensionalVector.at( x ).at( y ) );
}
}
}
在 Matrix::set(int x, int y, double newValue )
内,始终检查 x 和 y 参数是否介于 -1 和 this->xLength && 介于 -1 和 this->yLength 之间。
但是如果 x 和 y 参数在(然后未初始化)this->values 范围内,则永远不会检查它们...
我不确定我是否应该在 Whosebug 或 CodeReview 上问这个问题。但是因为我找不到类似的问题,所以我把它贴在这里。
ATM 我正在优化一个简单的图像处理应用程序的代码。
其中一个目标就是把所有的卷积效果classes各自的矩阵作为自己的私有变量。因为 const-correctness 这并没有早点完成,但是解决引入的 const-correctness 问题的快速修复并不少于内存和 cpu-cycles。
所以我决定在 class-initialization-level 初始化卷积矩阵 std::vector<std::vector<double>>
因为创建数十个构造函数以使每个 std::array<std::array<double>,\d+>,\d+>
的初始化成为可能,效率低下。
BlurFilter::BlurFilter() : ColorEffect(), convolutionMatrix(
std::vector<std::vector<double>>{
std::vector<double>{ 0.0, 0.0, 1.0, 0.0, 0.0 },
std::vector<double>{ 0.0, 1.0, 1.0, 1.0, 0.0 },
std::vector<double>{ 1.0, 1.0, 1.0, 1.0, 1.0 },
std::vector<double>{ 0.0, 1.0, 1.0, 1.0, 0.0 },
std::vector<double>{ 0.0, 0.0, 1.0, 0.0, 0.0 }
} )
{
}
不过。应用程序在 Matrix 构造函数中运行时中断,出现 std::out_of_range
异常,what() 消息:
what(): vector::_M_range_check: __n (which is 0) >= this->size() (which is 0)"
又名 multidimensionalVector.size() 是 0.
Matrix::Matrix( const std::vector<std::vector<double>>& multidimensionalVector )
{
this->xLength = multidimensionalVector.size();
this->yLength = ( *multidimensionalVector.begin() ).size();
this->values = multidimensionalVector;
}
老实说,我不明白为什么 multidimentionalVector 的大小在那一刻根本为零,因为我正在传递一个初始化的向量向量,它可以是 - 如图所示 - 复制构造(或移动构造)转到矩阵 class 的值变量。更改 multidimensionalVector 按值复制不会有什么不同。
有人可以解释一下 and/or 这里出了什么问题吗?
(PS:我更喜欢用自己的话(也就是简单的英语)写的答案,而不是直接引用 C++ 标准文档,因为使用了模糊和令人困惑的 academic/scientific 语言) .
FWIW,您可以大大简化您的代码。这是一个有效的例子:
#include <iostream>
#include <vector>
struct Matrix
{
Matrix(const std::vector<std::vector<double>>& multidimensionalVector);
size_t xLength;
size_t yLength;
std::vector<std::vector<double>> values;
};
Matrix::Matrix( const std::vector<std::vector<double>>& multidimensionalVector ) : xLength(0), yLength(0), values(multidimensionalVector)
{
this->xLength = values.size();
std::cout << "xLength: " << xLength << std::endl;
if ( xLength > 0 )
{
this->yLength = ( *values.begin() ).size();;
}
std::cout << "yLength: " << yLength << std::endl;
}
struct BlurFilter
{
BlurFilter();
Matrix convolutionMatrix;
};
BlurFilter::BlurFilter() : convolutionMatrix( { { 0.0, 0.0, 1.0, 0.0, 0.0 },
{ 0.0, 1.0, 1.0, 1.0, 0.0 },
{ 1.0, 1.0, 1.0, 1.0, 1.0 },
{ 0.0, 1.0, 1.0, 1.0, 0.0 },
{ 0.0, 0.0, 1.0, 0.0, 0.0 } } )
{
}
int main()
{
BlurFilter f;
}
嗯,这让我很尴尬。
看来我在剥离和优化发布此问题的代码时无意中解决了自己的问题。在发布之前,我没有想过尝试简化代码。
放
this->values = multidimensionalVector;
完成任务。
似乎引发 std::out_of_range
异常的 Matrix-constructor 的原文是这样的:
Matrix::Matrix( const std::vector<std::vector<double>>& multidimensionalVector )
{
this->xLength = multidimensionalVector.size();
this->yLength = ( *multidimensionalVector.begin() ).size();
for( int x = 0; x < this->xLength; x++ )
{
for( int y = 0; y < this->yLength; y++ )
{
this->set( x, y, multidimensionalVector.at( x ).at( y ) );
}
}
}
在 Matrix::set(int x, int y, double newValue )
内,始终检查 x 和 y 参数是否介于 -1 和 this->xLength && 介于 -1 和 this->yLength 之间。
但是如果 x 和 y 参数在(然后未初始化)this->values 范围内,则永远不会检查它们...