0

Consider

#include <iostream>

// Print n x m - Matrix A
template<typename T, size_t N, size_t M>
void printMatrix(T (&A)[N][M]) {
    for(int i=0; i<N; ++i) { // Rows
        for(int j=0; j<M; ++j) { // Columns
            std::cout << A[i][j] << " ";
        }
        std::cout << "\n";
    }
}

int main() {
    int A[2][2] = { {1,2},{3,4} };

    printMatrix(A);
    
    return 0;
}

The code works and I can see that T is deduced from the argument but I'm wondering how exactly the compiler deduces the values of N and M.

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
handy
  • 696
  • 3
  • 9
  • 22
  • 1
    The same way it deduces `T`? – Sam Varshavchik Oct 22 '20 at 11:09
  • `T` is deduced from `A` whereas `A` is explicitly given. So that's clear. But `N` and `M` are "properties" of `A`. If I read `printMatrix(A)` I see one variable and that's `A` so for me it's not obvious that the compiler know what `N` and `M` refer to. – handy Oct 22 '20 at 11:17
  • Does this answer your question? [How does this "size of array" template function work?](https://stackoverflow.com/questions/3368883/how-does-this-size-of-array-template-function-work) – underscore_d Oct 22 '20 at 11:25
  • 1
    The compiler knows not only the name of an object, `A` but also its type. This is fundamental to C++. – Sam Varshavchik Oct 22 '20 at 11:31

1 Answers1

2

To better understand the situation, let's use lower-case variable names:

template<typename T, size_t N, size_t M>
void printMatrix(T (&a)[N][M]) {
    for(int i=0; i<N; ++i) { // Rows
        for(int j=0; j<M; ++j) { // Columns
            std::cout << a[i][j] << " ";
        }
        std::cout << "\n";
    }
}

int main() {
    int a[2][2] = { {1,2},{3,4} };

    printMatrix(a);
    
    return 0;
}

(A was changed to a). Now let's observe, that the type of a is int[2][2]. This is the type that gets inferred by the compiler, that is also capable of breaking it down into components.

erenon
  • 18,838
  • 2
  • 61
  • 93