Шаблоны функций. Аргументы по умолчанию. С++11

Сайт не является учебником по программированию. Это только небольшой авторский сборник информации в помощь начинающим программистам.

Это небольшая статья показывает маленький фокус с обработкой матриц. До С++11 обработка двумерных и более мерных матриц внутри функций требовала того, чтобы программисты С++ явно указывали саму матрицу и ее размеры. Либо использования двумерного массива как одномерного, либо другого извращенного варианта. Язык С++ развивается и дополняется различными возможностями. С одной стороны это плохо, с другой удобства — это удобства. Поэтому простой прием обработки двумерного статически создаваемого массива внутри функции.

У нас с Вами будет очень простая задача. Показать двумерный массив на экране при помощи функции.

Вот наш массив

int m[3][3] {{ 1, 2, 3}, {4, 5, 6}, { 8, 9, 10}};

Прошу заметить, что это не массив **, а массив [][], т.е. статически создаваемый. Вот этот массив мы и будем выводить на экран. Начнем с самого простого способа, используя возможности С++11.

Благодаря тому, что количество строк и столбцов в этом массиве одинаковое, можно обработать его с помощью функции очень даже простым способом.

Из-за того, что размеры строк и колонок одинаковые, нам не нужно дополнительно узнавать сколько там у массива получилось в пустых скобках. Мы ведь итак знаем, что у него число строк и колонок одинаковое. Удивительно, но этот код прекрасно работает благодаря тому, что мы использовали шаблон, в котором указали аргумент по умолчанию.

Но что делать, если массив не такой "ровный", а прямоугольный, где число строк и колонок разнится. То, что массив способен распознать часть своего размера не обозначает, что это сможем сделать мы, да и этот показанный прием даст сбой. Вот пример такого сбоя.

И на экране нет массива! Сбой, прием не работает. Это не сбой, это наша (в текущей ситуации моя) ошибка. Достаточно посмотреть, что получается в size1 и в size2 с помощью cout. (Думаю, это Вы осилите и без моей помощи). Получим массив [0][4]. Когда функция foo инстанирует шаблон, то этот шаблон создаст массив m[0][4], а это совсем не наш [3][4]. Вы же можете создать, например, нулевой массив int Arr[0][0]; А заполнить? Но то только пол беды. А если бы и не ноль строк, узнать число элементов сам массив может и может, а мы вот по идее не можем. Внутри функции получается указатель, а размер указателя — это не размер массива. В первом успешном варианте нас спасло то, что мы знали, что число строк и колонок одинаковое, а сейчас-то нам число строк неизвестно совсем. Но, решение есть и оно, как оказывается, очень даже не сложное. Я для наглядности size1 и size2 поменяю на Row и Col соответственно, это не должно Вас смутить.

Несложно же. И это работает. До C++11 компиляторы не захотят компилировать эти коды, но время не стоит на месте. В завершении приведу еще один пример, не знаю насколько он полезен или же бесполезен, но он может оказаться весьма интересным для изучения возможностей языка C++. Вернем ссылку на двумерный массив.

static нужен для того, чтобы по завершению работы функций, массив не самоубился. Вспоминаем о том, что все локальные переменные, созданные внутри функции по завершению функции умирают. А массив — это переменная. Поэтому в этом варианте ключевое слово static очень нам пригодилось.

Все комментарии на сайте проверяются, поэтому ваш комментарий может появиться не сразу. Для вставки кода в комментарий используйте теги: [php]ВАШ_КОД[/php]

Добавить комментарий

Ваш e-mail не будет опубликован.

Поиск

 
     
Яндекс.Метрика

НАГРАДИ АВТОРА САЙТА
WEBMONEY
R375024497470
U251140483387
Z301246203264
E149319127674

Солидной компании на постоянную работу требуется девушка приятной внешности со знанием Linux, программирование встраиваемых микроконтроллеров на C/C++/ASM, знание Linux - установка и настройка (сеть, графика, установка драйверов); C , Python, технологии ООП, GTK (желательно PyGTK) или Qt, SQL и XML - базовые знания; понимание многопоточности и синхронизации потоков.

Выражаю свою признательность

  • Максиму очень признателен за указание на мои ошибки и неточности.
  • Sergio ===> за оказание помощи в исправлении моих ошибок
  • Gen ===> за правильное стремление помочь другим новичкам и выявления моих ошибок