Равномерная инициализация вызывает ошибку времени выполнения в C ++ - PullRequest
0 голосов
/ 11 декабря 2018

Я большой поклонник равномерной инициализации, и я использую ее в большинстве случаев, когда я хочу создать инициализированную переменную.Недавно я столкнулся со странной ошибкой при создании переменной типа 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 };

, следующая ошибка показываетup

malloc_consolidate (): неверный размер чанка

Я все еще не совсем уверен, что радует.Используется ли другой конструктор (чем предполагалось)?Может кто-нибудь объяснить, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Использование {...} для создания объекта называется "list-initialization" .

cv::Mat предоставляет конструктору, принимающему std::initializer_list: https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/mat.hpp#L1007

Существует специальное правило в разрешении перегрузки , которое всегда отдает приоритет конструкторам, принимающим std::initializer_list, если используется list-initialization ,независимо от существования других конструкторов, которые могут потребовать менее явных преобразований.

Вызов cv::Mat(...) полностью отличается от cv::Mat{...}.


Моя ментальная модель для этого такова: еслиобъект, который вы создаете, является контейнером, тогда {...}, скорее всего, будет вести себя не так, как (...), поэтому вы должны быть осторожны.В противном случае предпочитайте {...}.

0 голосов
/ 11 декабря 2018

cv::Mat lookUpTable{ 1, 256, CV_8U } вызывает конструктор, отличный от cv::Mat lookUpTable( 1, 256, CV_8U ).cv::Mat lookUpTable{ 1, 256, CV_8U } - это прямая инициализация списка , и поскольку cv::Mat имеет конструктор, принимающий std::initlizer_list, этот конструктор будет вызываться вместо 3 параметров, которые делает первый вызов.Это означает, что у вас есть матрица, содержащая элементы { 1, 256, CV_8U }, вместо матрицы из 256 элементов.

На CppCon2018 Николай Йосуттис очень хорошо говорит об «однородности» равномерной инициализации: https://www.youtube.com/watch?v=7DTlWPgX6zs

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...