jeudi 7 janvier 2021

In a template argument, what rules allow the compiler to infer the number of items of an array?

Given the two programs bellow -- identical except for the definition of the template function len():

// ================================
//  a.cc
// ================================
#include <iostream>

template<class T, std::size_t n>
std::size_t len(T (&v)[n]) { return n; }

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

    std::cout << len(arr) << std::endl;
}
// ================================
//  b.cc
// ================================
#include <iostream>

template<class T, std::size_t n>
std::size_t len(T v[n]) { return n; }

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

    std::cout << len(arr) << std::endl;
}

When using g++, the first program compiles and runs as expected. But the second does not compile. Here is the diagnostic:

b.cc: In function ‘int main()’:
b.cc:13:25: error: no matching function for call to ‘len(int [3])’
     std::cout << len(arr) << std::endl;
                         ^
b.cc:7:13: note: candidate: template<class T, long unsigned int n> std::size_t len(T*)
 std::size_t len(T v[n]) { return n; }
             ^
b.cc:7:13: note:   template argument deduction/substitution failed:
b.cc:13:25: note:   couldn't deduce template parameter ‘n’
     std::cout << len(arr) << std::endl;

Why is the compiler able to infer the number of items in the array in the first case but not in the second? What makes, in the C++11 or C++17 standard, mandatory to write T (&v)[n] instead of T v[n]?

Aucun commentaire:

Enregistrer un commentaire