Мне нужно написать шаблон, который меняет местами диагонали матрицы. При компиляции выдает ошибку и не знаю как исправить. Подскажите.
#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
template <typename T>
T diagonal(T **array, int size) {
T buf;
for(int i=0;i<size;i++){
buf=array[i][i];
array[i][i]=array[i][(size-1)-i];
array[i][(size-1)-i]=buf;
}
return buf;
}
int main() {
setlocale(LC_ALL,"Russian");
int size=3;
int m[size][size];
for(int i=0;i<size;++i){
for(int j=0;j<size;++j){
cout << "ВВод " << i <<" " << j << ":";
cin>>m[i][j];
}
}
diagonal(m,size);
for(int i=0;i<size;++i){
for(int j=0;j<size;++j)
cout<<m[i][j]<<' ';
cout<<endl;
}
system("pause");
return 0;
}
Основная ошибка не имеет отношения к шаблонам вообще. Вы, очевидно, полагаете, что к массиву вида T a[m][n] можно доступаться через "двойной указатель" T **p. Это не так. Эти типы никак не связаны вообще. Встроенный двухмерный массив в С/С++ никак не совместим с "двойным указателем".
А что желать дальше зависит от ваших намерений. Можно вообще написать просто
template <typename T>
void diagonal(T &array, int size) {
std::decay_t<decltype(array[0][0])> buf;
for(int i=0;i<size;i++){
buf=array[i][i];
array[i][i]=array[i][(size-1)-i];
array[i][(size-1)-i]=buf;
}
}
или
template <typename T>
void diagonal(T &array, int size)
{
using std::swap;
for (int i = 0; i < size; ++i)
swap(array[i][i], array[i][size - 1 - i]);
}
тем самым соблюдя принцип "duck typing" шаблонного программирования: все, что нас интересует, это чтобы аргумент поддерживал lvalue выражения вида array[i][j], а уж какой конкретно тип имеет array и как он внутренне устроен нам не интересно.
(Кстати, зачем вы возвращаете последний buf из функции мне не совсем ясно.)
Но если вы хотите использовать именно T **, то от встроенного массива T a[m][n] в качестве аргумента придется отказаться. Придется строить вручную jagged array, т.е. массив указателей на массивы.
Это во-первых. Во-вторых, в С++ нет и никогда не было такого
int size=3;
int m[size][size];
Размер массива в С++ обязан быть константой времени компиляции. Даже если ваш компилятор поддерживает подобные расширенные объявления, мой вариант выше но позволить использовать такой нестандартный тип массива в качестве параметра шаблона.
T** реализуется как массив указателей на одномерные массивы, а T[][] как массив длиной size*size, отсюда два варианта на скорую руку
Изменить m на динамический массив
int **m = new int*[size];
for (int i = 0; i < size; i++) m[i] = new int[size];
Поправить шаблон и вызов
template <typename T, int size> void diagonal(T array[size][size]) {...}
diagonal<int, size>(m);
Может есть варианты по красивее, но на ночь не вспомнил.
template <typename T> void diagonal(T *array, int size) { и работать с адресацией типа i*size+jДля начала следует избавится от массивов в стиле С. Вместо них следует использовать ::std::array. Тогда функцию можно записать вот так (тип и размер выводятся):
#include <array>
#include <cstddef>
template<typename T, ::std::size_t size> void // ничего не возвращаем
diagonal(::std::array<::std::array<T, size>, size> & mat)
...
constexpr const ::std::size_t size{3}; // размер массива должен быть константой времени компиляции в любом случае
::std::array<::std::array<int, size>, size> m;
Если же хочется непременно с обычными массивами, то можно модифицировать так:
template<typename T, ::std::size_t size> void
diagonal(T ( & mat )[size][size])
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости