I've stumbled upon this typedef:
typedef char (&small)[1];
typedef char (&large)[2];
I know & either as the reference qualifier or the address-of-operator. Since we are dealing with types here, I'd guess it's a reference, but do the parenthesis have a special purpose?
In the context I got it from it is used to perform a compile time check for convertibility of types, how can this typedef help in this matter?
The typedefs define references to arrays of char: small is an array of one char and large as an array of two char. The purpose of typedefs of this kind is to have them returned from a property checker based on overloading: if the property exists one is returned otherwise the other is returned. The result is then used sizeof() to determine the property, e.g.:
template <typename B, typename S>
struct is_base_of_helper {
static small test(B*);
static large test(void*, ...);
};
template <typename B, typename S>
struct is_base_of {
enum value { 1 == sizeof(is_base_of_helper<B, S>::test(static_cast<S*>(0)) };
};
The test may semantically not be quite accurate but the idea is: call an overloaded function in a sizeof() operation and test the size of the result. Depending on which overload is chosen the presence of a type property can be determined. Using references to arrays has the nice property that their size can be predicated (1 and 2 for small and large, respectively). Using, e.g., the size of built-in types doesn't work reliably because they can all have the same size.
... and, yes, the parenthesis matter: without the parenthesis it would be an illegal attempt to create an array of references rather than a reference to an array. Only the latter gives the size guarantees this is after.
These statements typedef reference to array of size one, and size two respectively. This is an example:
/*
foo accepts arrays of size 10 only!
*/
void foo(int (&array)[10])
{ ... }
another example:
/*
foo accepts arrays of size len!
The size is len, so you can know the size of the array
unlike when using a pointer to int.
(unless you pass the size in the next parameter, of course!)
*/
template <std::size_t len>
void foo(int (&array)[len])
{ ... }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With