Why does the following not compile
#include <iostream>
template <typename T, size_t N>
const size_t len(T[N]){
return N;
}
int main(int argc, char* argv[]) {
using namespace std;
int arr[] = {1, 2, 3};
cout << len(arr);
}
but this does:
#include <iostream>
const size_t foo(int[3]) {
return 42;
}
int main(int argc, char* argv[]) {
using namespace std;
int arr[1] = {123};
cout << foo(arr);
}
but with obviously incorrect argument and strangely only with the parameter identifier omitted
I am using GCC 4.9.2 with -std=c++1y
edit:
the error message for the first example:
main.cpp:12:24: error: no matching function for call to 'len(int [3])'
cout << len(arr);
^
main.cpp:12:24: note: candidate is:
main.cpp:4:18: note: template<class T, unsigned int N> const size_t len(T*)
const size_t len(T[N]){
^
main.cpp:4:18: note: template argument deduction/substitution failed:
main.cpp:12:24: note: couldn't deduce template parameter 'N'
cout << len(arr);
^
A function argument that looks like an array is actually a pointer, for bizarre historical reasons. If you specify an array size, then it's ignored. So the template is equivalent to
template <typename T, size_t N>
const size_t len(T*){
return N;
}
The argument can be pointer or anything convertible to one, including an array of any size, so N
cannot be deduced from the argument. You can fix this by taking the array by reference:
template <typename T, size_t N>
size_t len(T(&)[N]){
return N;
}
Now the argument can only be an array of known size, and N
will be deduced from that size.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.