Préambule: je tiens tout d'abord à préciser que je ne suis pas spécialement un développeur C++ (question concepts, idiomes, etc.) De plus comme ce n'est pas mon activité principale ; je n'ai pas d'IDE "spécialisé" C++ à disposition et donc le code présenté ci-après à été réalisé via un éditeur disponible sur navigateur (du type Ideone pour ceux qui connaissent) et donc je n'ai pas le contrôle sur l'environnement (options de compilation par exemple) ni la possibilité de séparer le code dans plusieurs fichiers (même si j'ai tenté de coder de manière que chaque élément n'est que ce qu'il a besoin dans sa portée) ; je vous prie donc de tenir compte de ces éléments

Suite à une question posée sur le chat de développez où il était question de faire la somme des diagonales d'une matrice carrée (dans un sens puis dans l'autre) ; j'ai expérimenté dans plusieurs langages avec une approche basée sur le code Matlab suivant
Code Matlab : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
M = [  1   2   3
      10  20  30
     100 200 300];
N = size(M,1)-1;
 
diags     = arrayfun(@(k) sum(diag(M ,k)),        -N:N)
antidiags = arrayfun(@(k) sum(diag(flipud(M),k)), -N:N)
Je pense que le code reste compréhensible même sans connaître Matlab

Pour C++, afin de m'exercer j'ai voulu tenter une approche template (que je suis loin de maitriser) et en suis arrivé à ceci (attention risque de piquer les yeux )
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <array>       // std::array
#include <cstdlib>     // std::size_t, std::abs, std::min
 
namespace sehn {
    template <typename T, std::size_t N>
    using matrix = std::array<std::array<T, N>, N>;
 
    template <typename T, std::size_t N>
    matrix<T, N> flipud (matrix<T, N> const &);
 
    template <typename T, std::size_t N>
    using all_diags = std::array<T, 2 * N - 1>;
}
 
template <typename T, std::size_t N>
sehn::all_diags<int, N> sum_diags (sehn::matrix<T, N> const &);
 
template <typename T, std::size_t N>
void print_array (std::array<T, N> const &);
 
template <typename T, std::size_t N>
void print_matrix (sehn::matrix<T, N> const &);
 
int main () {
    std::size_t const size (3);
    sehn::matrix<int, size> matrix { {
         1,   2,   3,
        10,  20,  30,
       100, 200, 300
    } };
 
    print_matrix (matrix);
    print_array (sum_diags (matrix));
 
    auto flipped (sehn::flipud (matrix));
 
    print_matrix (flipped);
    print_array (sum_diags (flipped));
 
    return 0;
}
 
#include <iostream>    // std::cout, std::endl
 
template <typename T, std::size_t N>
void print_array (std::array<T, N> const &array) {
    for (auto const &item : array)
        std::cout << item << '\t';
    std::cout << std::endl;
}
 
template <typename T, std::size_t N>
void print_matrix (sehn::matrix<T, N> const &matrix) {
    for (auto const &row : matrix)
        print_array (row);
    std::cout << std::endl;
}
 
#include <type_traits> // std::enable_if
 
template <std::size_t N, int K>
using K_before_N = typename std::enable_if<K < static_cast<int> (N) - 1>::type;
 
template <typename T, std::size_t N, int K>
K_before_N<N, K> sum_diags_impl (sehn::matrix<T, N> const &, sehn::all_diags<int, N> &);
 
template <std::size_t N, int K>
using K_at_N = typename std::enable_if<K == static_cast<int> (N) - 1>::type;
 
template <typename T, std::size_t N, int K>
K_at_N<N, K> sum_diags_impl (sehn::matrix<T, N> const &, sehn::all_diags<int, N> &);
 
template <typename T, std::size_t N>
sehn::all_diags<int, N> sum_diags (sehn::matrix<T, N> const &matrix) {
    sehn::all_diags<int, N> sums;
    sum_diags_impl<T, N, -static_cast<int> (N) + 1> (matrix, sums);
    return sums;
}
 
namespace sehn {
    template <typename T, std::size_t N, int K>
    using diagonal = std::array<T, N - std::abs (K)>;
 
    template <typename T, std::size_t N, int K>
    diagonal<T, N, K> diag (matrix<T, N> const &);
}
 
#include <iterator>    // std::begin, std::end
#include <numeric>     // std::accumulate
 
template <typename T, std::size_t N, int K>
K_before_N<N, K> sum_diags_impl (sehn::matrix<T, N> const &matrix, sehn::all_diags<int, N> &sums) {
    auto diag = sehn::diag<T, N, K> (matrix);
    sums[N - 1 + K] = std::accumulate (std::begin (diag), std::end (diag), T{});
    sum_diags_impl<T, N, K + 1> (matrix, sums);
}
 
template <typename T, std::size_t N, int K>
K_at_N<N, K> sum_diags_impl (sehn::matrix<T, N> const &matrix, sehn::all_diags<int, N> &sums) {
    auto diag = sehn::diag<T, N, K> (matrix);
    sums[N - 1 + K] = std::accumulate (std::begin (diag), std::end (diag), T{});
}
 
#include <algorithm>   // std::reverse_copy
 
namespace sehn {
    template <typename T, std::size_t N>
    matrix<T, N> flipud (matrix<T, N> const &source) {
        matrix<T, N> flipped;
        std::reverse_copy (std::begin (source), std::end (source), std::begin (flipped));
        return flipped;
    }
 
    template <typename T, std::size_t N, int K>
    diagonal<T, N, K> diag (matrix<T, N> const &matrix) {
        diagonal<T, N, K> diag;
 
        for (std::size_t row (0); row < N; ++row) {
            std::size_t const col (row + K);
            diag[std::min (row, col)] = matrix[row][col];
        }
 
        return diag;
    }
}
Tout fonctionne à priori correctement (j'avoue ne pas avoir poussé les tests très loin ; arriver à avoir un code qui compile et donne le bon résultat sur mon petit cas d'essai est déjà gratifiant en soi pour moi).
Mon "souci" se pose en fait sur l'include d'algorithm ; e l'état ça fonctionne ; mais si je ne fais pas l'alias diagonal (ligne 82) je me fait insulter copieusement ; sauf si je déplace l'include avant ce bloc namespace ; ci-joint le type de message que je reçois.
Code Text : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
/tmp/cc5OQUfq.o: In function `_Z14sum_diags_implIiLm3ELin2EENSt9enable_ifIXltT1_misciT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE':
prog.cpp:(.text._Z14sum_diags_implIiLm3ELin2EENSt9enable_ifIXltT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE[_Z14sum_diags_implIiLm3ELin2EENSt9enable_ifIXltT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE]+0x1d): undefined reference to `std::array<int, (3ul)-(abs(-2))> sehn::diag<int, 3ul, -2>(std::array<std::array<int, 3ul>, 3ul> const&)'
/tmp/cc5OQUfq.o: In function `_Z14sum_diags_implIiLm3ELin1EENSt9enable_ifIXltT1_misciT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE':
prog.cpp:(.text._Z14sum_diags_implIiLm3ELin1EENSt9enable_ifIXltT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE[_Z14sum_diags_implIiLm3ELin1EENSt9enable_ifIXltT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE]+0x1d): undefined reference to `std::array<int, (3ul)-(abs(-1))> sehn::diag<int, 3ul, -1>(std::array<std::array<int, 3ul>, 3ul> const&)'
/tmp/cc5OQUfq.o: In function `_Z14sum_diags_implIiLm3ELi0EENSt9enable_ifIXltT1_misciT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE':
prog.cpp:(.text._Z14sum_diags_implIiLm3ELi0EENSt9enable_ifIXltT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE[_Z14sum_diags_implIiLm3ELi0EENSt9enable_ifIXltT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE]+0x1d): undefined reference to `std::array<int, (3ul)-(abs(0))> sehn::diag<int, 3ul, 0>(std::array<std::array<int, 3ul>, 3ul> const&)'
/tmp/cc5OQUfq.o: In function `_Z14sum_diags_implIiLm3ELi1EENSt9enable_ifIXltT1_misciT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE':
prog.cpp:(.text._Z14sum_diags_implIiLm3ELi1EENSt9enable_ifIXltT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE[_Z14sum_diags_implIiLm3ELi1EENSt9enable_ifIXltT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE]+0x1d): undefined reference to `std::array<int, (3ul)-(abs(1))> sehn::diag<int, 3ul, 1>(std::array<std::array<int, 3ul>, 3ul> const&)'
/tmp/cc5OQUfq.o: In function `_Z14sum_diags_implIiLm3ELi2EENSt9enable_ifIXeqT1_misciT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE':
prog.cpp:(.text._Z14sum_diags_implIiLm3ELi2EENSt9enable_ifIXeqT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE[_Z14sum_diags_implIiLm3ELi2EENSt9enable_ifIXeqT1_micviT0_Li1EEvE4typeERKSt5arrayIS3_IT_XT0_EEXT0_EERS3_IiXmimlLi2ET0_Li1EEE]+0x1d): undefined reference to `std::array<int, (3ul)-(abs(2))> sehn::diag<int, 3ul, 2>(std::array<std::array<int, 3ul>, 3ul> const&)'
collect2: error: ld returned 1 exit status
Du coup je me tourne vers vous pour essayer de comprendre le phénomène (et tant qu'à faire si vous avez des remarques sur le code [pas forcément sur l'algo étant donné que j'ai pris le parti de reproduire celui du code matlab] )

Cordialement !