I need to write a pattern that swaps the diagonal of the matrix. When compiling, it gives an error and I do not know how to fix it. Tell me.

#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; } 
  • And what is written in the error? (add to the question itself) - VTT
  • @VTT Severity Error C2672 "Dia": the corresponding overloaded function Error C2784 T was not found Dia (const T **, int): the template argument for "const T **" could not be derived from "int [3] [3]" - Kolax

3 answers 3

The basic error is not related to patterns at all. You obviously believe that an array of the form T a[m][n] can be accessed through the "double pointer" T **p . This is not true. These types are not related at all. The built-in two-dimensional array in C / C ++ is not compatible with "double pointer" at all.

And what to wish further depends on your intentions. You can even write just

 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; } } 

or

 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]); } 

thus, following the principle of "duck typing" of template programming: all that interests us is that the argument supports lvalue expressions of the form array[i][j] , and what type exactly has an array and how it is internally organized is not interesting for us.

(By the way, why are you returning the last buf from the function is not entirely clear to me.)

But if you want to use T ** , then the built-in array T a[m][n] as an argument will have to be abandoned. You have to build the jagged array manually, i.e. array of pointers to arrays.

This is the first. Secondly, in C ++ there is never such a thing.

 int size=3; int m[size][size]; 

The size of the array in C ++ must be a compile-time constant. Even if your compiler supports such extended declarations, my option is higher, but allow using such a non-standard array type as a template parameter.

    T** is implemented as an array of pointers to one-dimensional arrays, and T[][] as an array of length size*size , hence there are two options in a hurry

    1. Change m to dynamic array

       int **m = new int*[size]; for (int i = 0; i < size; i++) m[i] = new int[size]; 
    2. Correct pattern and challenge

       template <typename T, int size> void diagonal(T array[size][size]) {...} diagonal<int, size>(m); 

    Maybe there are more beautiful options, but did not remember at night.

    1. You can make the template <typename T> void diagonal(T *array, int size) { and work with the addressing type i*size+j

      First you should get rid of the arrays in the style of C. Instead, you should use ::std::array . Then the function can be written like this (type and size are output):

       #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; 

      If you really want with ordinary arrays, you can modify it like this:

       template<typename T, ::std::size_t size> void diagonal(T ( & mat )[size][size]) 
      • one
        :: tear out :: eye :: all :: yet. using here is probably useless. - αλεχολυτ
      • @alexolut using here is really useless (left over from the copy-paste code from the question), but about the :: complex :: names this is actually not a question for me. - VTT
      • @alexolut, you also tell me how not to use the namespace in the code for those who have projects with ten implementations of map / vector / list / set and as many other similar classes with different functionality. At the same time, print MS for c # and Sun for java. Oh yeah, how are things going in the srs stl pluses? Probably, MS did not do well here either ... - test123
      • @ test123 it seems to me that you should ask a separate question , since the topic you are talking about is quite extensive. - αλεχολυτ