The code in question:
_Ty (&_Array)[_Size]
is a reference to a compile-time deduced array of type _Ty
with size _Size
.
Due to the way operator precedence works in C++, the actual types themselves are named somewhat strange to avoid syntactic ambiguities -- which is where the round brackets around the &
and name exist.
All array types can be generalized to the form:
T [N]
-- an array of known size of T
elements (the "value type")
T (&) [N]
-- a reference to an array (such as the one in (1))
T (*) [N]
-- a pointer to an array (such as the one in (1))
Where T
may be possibly CV-qualified
Using this in a template just allows for the T
and N
types to be deduced.
Template type and non-type arguments can be deduced in function signatures when they are used for argument types, which is what this template is doing. If we clean it up some by removing the underscores, it would look something like:
template <class T, size_t N>
constexpr T* begin(T (&array)[N]) noexcept {
return array;
}
This allows for both the type T
and the array size N
to be deduced, provided the type is an array. When being returned as a T*
, it's relying on array-to-pointer decaying to produce a pointer.
Note: The _NODISCARD
is likely just a compile-time macro evaluating to [[nodiscard]]
when in C++17 mode, and either no attribute or a compiler-specific attribute like __attribute__((warn_unused_result))
in pre-C++17 mode.