#c #arrays #templates #function
#c #массивы #шаблоны #функция
Вопрос:
У меня есть 2 2D-массива, которые представляют собой лабиринт
const char maze1[10][11]
и const char maze2[20][21]
Я пытаюсь создать 1 функцию для обработки обоих лабиринтов следующим образом:
void solveMaze(maze[][])
{
}
и просто пройти лабиринт, как solveMaze(maze1);
Как бы я сделал это с помощью шаблонов функций?
Я недавно уже задавал этот вопрос, но явно просил не использовать шаблоны функций, потому что я не был уверен, как его использовать, но я хотел бы посмотреть, как это будет работать. (надеюсь, это не «злоупотребление» системой)
Комментарии:
1. Я не думаю, что это можно было бы сделать с помощью шаблонов. Вы бы использовали шаблоны, если вам нужен лабиринт символов, лабиринт int или лабиринт с плавающей запятой, а не только лабиринты символов с разными размерами.
2. @ChadSchouggins: на самом деле, размеры массива могут быть параметрами шаблона. Каноническим примером является шаблонная функция для получения размера массива:
template <typename T, size_t N> size_t size(T (amp;)[N]) { return N; }
. Однако синтаксис является загадочным.3. @codeCube: это может иметь смысл, поскольку параметры шаблона являются константами, это может позволить компилятору выполнять определенные оптимизации для некоторых размеров. Здесь это сомнительно, но однажды может помочь.
4. @codeCube: Вы не совсем правы. Я могу вспомнить пару случаев, когда вы хотите использовать целочисленную константу в качестве параметра шаблона. В качестве примера можно привести шаблонный класс битовых полей произвольного размера.
Ответ №1:
Вам не нужно и не следует использовать шаблоны для решения этой проблемы. Все, что вы делаете, это решаете лабиринты разных размеров.
Шаблоны предназначены для создания нескольких классов / функций, которые используют различные типы.
Вместо этого создайте класс для хранения лабиринта. Этот класс должен хранить размеры лабиринта и предоставлять доступ к компонентам этого лабиринта.
Ответ №2:
Прежде всего, было бы намного проще, если бы вы использовали лучшие массивы. Проблема с C-массивами заключается в том, что они имеют тенденцию легко распадаться на указатели, и как только они это делают, размер теряется (и это, моя дорогая, довольно глупо, насколько я понимаю …)
Затем выбор зависит от того, есть ли у вас массивы фиксированного размера или нужны массивы с динамическим размером:
- для фиксированного размера:
std::array
(или, если недоступноboost::array
) - для динамически изменяемого размера:
std::vector
Поскольку шаблон будет иметь больше смысла в данном std::array
случае, я полагаю, что это то, что вы выбрали.
char const maze1[10][11]
эквивалентно
std::array<std::array<char, 11>, 10> const maze1
Он немного более подробный, но std::array
предлагает обычные методы-члены, такие как .size()
, .begin()
, .end()
, и т. Д., И его можно легко передать в функциях.
Теперь перейдем к вашим шаблонным функциям. Подпись будет просто:
template <size_t M, size_t N>
void solveMaze(std::array<std::array<char, N>, M> constamp; maze);
Однако, несмотря на ваш вопрос, вы, скорее всего, не захотите использовать шаблоны здесь (они приносят мало пользы). Поэтому я бы посоветовал использовать vector
и обычные функции:
void solveMaze(std::vector< std::vector<char> > constamp; maze);
Ответ №3:
template<int w, int h>
void solveMaze(const char (amp;maze)[w][h])
{
//can use w,h now
}
Ответ №4:
Реальной поддержки многомерных массивов нет. Вам следует рассмотреть возможность использования класса с надлежащей поддержкой измерений. Следующее делает трюк
template<int N, int M>
void solveMaze(const char (amp;maze)[N][M]) {
size_t n = N;
size_t m = M;
int x = 0;
}
int main(int argc, char *argv[])
{
const char maze[3][2] = { { 0, 1} , {2, 3}, {4, 5} };
solveMaze(maze);
return 0;
}
Комментарии:
1. Очень интересно. Из любопытства, почему вы передаете эти переменные в main? необходимы ли они для этого?
2. @dukevin какие переменные — argc и argv? В этом нет необходимости — это то, как, по мнению моей IDE, должен выглядеть main: P