Reputation: 159
I have an example function which takes a reference to an array. The number of elements in the function definition is unknown.
template<typename T, std::size_t N>
void someFun(T (&)[N])
{
/* ... */
}
Calling this function for an array of one element is compiling fine.
Deduced param type is int (&)[1]
.
int main()
{
int arr[1];
someFun(arr);
}
The problem is, when I'm trying to pass an array of zero elements. Example below shows the code and error.
int main()
{
int arr[0];
someFun(arr);
}
Compilation error (using g++ 7.2):
../src/main.cpp: In function 'int main()':
../src/main.cpp:24:13: error: no matching function for call to 'someFun(int [0])'
someFun(arr);
^
../src/main.cpp:9:6: note: candidate: template<class T, long unsigned int N> void someFun(T (&)[N])
void someFun(T (&a)[N])
^~~~~~~
../src/main.cpp:9:6: note: template argument deduction/substitution failed:
make: *** [src/main.o] Error 1
I assume that deduced template param type is int (&)[0]
, however the substitution of this argument failed. I can go around by overloading someFun
. Here is my working example:
template<typename T, std::size_t N>
void someFun(T (&)[N])
{
/* ... */
}
template<typename T>
void someFun(T (&)[0])
{
/* ... */
}
int main()
{
int arr[0];
someFun(arr);
}
Running this code leads to a call to void someFun(T (&)[0])
function and deduced param type is int (&)[0]
. Could you please explain why I can't use more generic solution for an array of zero elements? Please don't judge the reason of this code. It is just an example for learning purposes.
Upvotes: 2
Views: 759
Reputation: 10939
Arrays of zero size are definitely not standard C++. From [dcl.array]:
In a declaration
T
D
whereD
has the form
D1 [ constant-expressionopt ] attribute-specifier-seqopt
[...]
If the constant-expression is present, it shall be a converted constant expression of type
std::size_t
and its value shall be greater than zero.
GCC however provides arrays of zero length as an extension but since they are non-standard you can't expect them to work together with other language features, such as template argument deduction. You could make an explicit overload of the function for zero length arrays.
#include <cstdlib>
template<typename T, std::size_t N>
void someFun(T (&)[N]) {}
template<typename T>
void someFun(T (&)[0]) {}
int main() {
int arr[0];
someFun(arr);
}
This compiles on GCC (7.2.0) but not on Clang (6.0.0).
Upvotes: 2