【问题标题】:Uniform initialization causes runtime error in C++统一初始化导致 C++ 中的运行时错误
【发布时间】:2018-12-11 15:43:29
【问题描述】:

我非常喜欢统一初始化,并且在大多数情况下,当我想构造初始化变量时,我都会使用它。最近,我在构造cv::Mat 类型的变量时遇到了奇怪的错误。

cv::Mat lookUpTable( 1, 256, CV_8U );
uchar* p = lookUpTable.ptr();

for( int i = 0; i < 256; ++i )
{
    p[i] = cv::saturate_cast<uchar>( pow( i / 255.0, gamma ) * 255.0 );
}

虽然这个实现效果很好,但如果使用统一初始化

cv::Mat lookUpTable{ 1, 256, CV_8U };

出现以下错误

malloc_consolidate(): 无效的块大小

我仍然不确定发生了什么。是否使用了不同的构造函数(而不是假设的)?有人可以进一步解释吗?

【问题讨论】:

  • 看起来统一初始化弊大于利
  • 我想知道在这之后你是否还会认为自己是统一初始化的粉丝。 :P
  • @HolyBlackCat 希望不再是那么大的粉丝

标签: c++ opencv uniform-initialization


【解决方案1】:

cv::Mat lookUpTable{ 1, 256, CV_8U } 调用与cv::Mat lookUpTable( 1, 256, CV_8U ) 不同的构造函数。 cv::Mat lookUpTable{ 1, 256, CV_8U }direct-list-initialization 并且由于 cv::Mat 有一个接受 std::initlizer_list 的构造函数,因此将调用该构造函数,而不是第一次调用的 3 参数。这意味着您有一个包含元素 { 1, 256, CV_8U } 的矩阵,而不是 256 个元素的矩阵。

Nicolai Josuttis 在 CppCon2018 上有一个关于统一初始化的“一致性”的精彩演讲:https://www.youtube.com/watch?v=7DTlWPgX6zs

【讨论】:

    【解决方案2】:

    使用{...}构造一个对象叫做“list-initialization”

    cv::Mat 提供了一个采用std::initializer_list 的构造函数: https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/mat.hpp#L1007

    重载决议中有一个special rule,如果使用list-initialization总是优先考虑采用std::initializer_list的构造函数,无论是否存在可能需要较少隐式转换的其他构造函数。

    调用cv::Mat(...)cv::Mat{...} 完全不同。


    对此我的心智模型是:如果您正在构建的对象是一个容器,那么{...} 的行为可能与(...) 不同,因此您应该小心。否则,首选{...}

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-21
      • 2014-09-13
      • 1970-01-01
      • 2021-11-28
      • 1970-01-01
      • 2013-07-26
      • 2011-09-17
      • 2015-08-11
      相关资源
      最近更新 更多