在 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 范围内,则永远不会检查它们...