C : шаблоны функций

#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