Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does this typedef mean and what is it good for?

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?

like image 471
mel- Avatar asked Dec 05 '25 19:12

mel-


2 Answers

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.

like image 157
Dietmar Kühl Avatar answered Dec 08 '25 11:12

Dietmar Kühl


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])
{ ... }
like image 41
Khaled Alshaya Avatar answered Dec 08 '25 12:12

Khaled Alshaya



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!