【问题标题】:Initialize std::vector in class's initializer list在类的初始化列表中初始化 std::vector
【发布时间】:2015-05-22 20:01:14
【问题描述】:

我不确定是否应该在 StackOverflow 或 CodeReview 提出这个问题。但是因为找不到类似的问题,所以在这里发布。

ATM 我正在​​优化一个简单的图像处理应用程序的代码。

其中一个目标是为所有卷积效果类赋予它们各自的矩阵作为它们的私有变量。因为 const-correctness 这不是早先完成的,但是解决 const-correctness 引入的问题的快速修复并不是内存和 cpu 周期。

所以我决定使用 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-exception 和 what()-message:

what(): vector::_M_range_check: __n (0) >= this->size() (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;
}

老实说,我不明白为什么此时 multidimentsionalVector 的大小为零,因为我正在传递一个初始化的向量向量,该向量可能是 - 如图所示 - 复制构造(或移动构造)到Matrix 类的值变量。按值更改 multidimensionalVector 复制并没有什么不同。

有人可以解释这里哪里和/或哪里出了问题吗?

(PS:我更喜欢用自己的话(也就是简单的英语)写答案,而不是直接从 C++ 标准文档中引用,因为使用了模糊和令人困惑的学术/科学语言)。

【问题讨论】:

  • 如果它是一个真正的矩阵,那么创建一个一维向量并使用索引计算(x + y * 宽度)来查找元素会更有效。为方便起见,您可以将其包装在一个类中。
  • 我们需要更多代码来帮助您。你能告诉我们你在哪里创建BlurFilter,以及矩阵是如何传递给Matrix的构造函数的吗?
  • 实际上标准并没有使用“模糊”的语言。神秘的,也许吧。令人困惑,当然对某些人来说。抽象,地狱是的。但含糊不清。是冗长的英语含糊不清且易于解释。
  • ideone.com/7VXnQk 工作正常。
  • 你试过一个非常基本的回购吗?我刚做了一个,它工作正常。它只是一个在构造函数中接受向量向量的类,将其分配给私有成员,然后主要创建一个实例,传入一个初始化的(如您所拥有的)向量向量。

标签: c++ c++11 multidimensional-array vector initialization


【解决方案1】:

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;
}

【讨论】:

  • 这太酷了!我有两个问题。我可以使用 convolutionMatrix[row][col] 访问 Matrix 元素吗?我可以创建一个std::unordered_map&lt; std::string , Matrix &gt; 来存储或指向这些东西吗?谢谢!。
  • 我认为它不适用于一维数组,是吗?我收到一个错误。
  • 如何在不提供初始化列表的情况下创建特定维度的矩阵?
  • @SimonWoodward,你可以使用BlurFilter::BlurFilter() : convolutionMatrix(M, std::vector&lt;double&gt;(N)) { }
【解决方案2】:

嗯,这让我很尴尬。

当我剥离和优化我的代码以发布此问题时,我似乎无意中解决了我自己的问题。在发布之前,我没有想过要试用简化的代码。

放置

this->values = multidimensionalVector;

完成了这项工作。

似乎引发std::out_of_range 异常的矩阵构造函数的原件是这样的:

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

【讨论】:

    猜你喜欢
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 2013-06-06
    • 1970-01-01
    • 1970-01-01
    • 2016-05-03
    • 2013-07-13
    • 2012-06-09
    相关资源
    最近更新 更多