Type trait to obtain default argument promotions

Viewed 684

[Disclaimer: I know an answer to this question. I thought it might be of some general interest.]

Question: How can we have a type trait that produces the type that results from performing default argument promotions?

Motivation: I would like to be able to use variable arguments portably. For example:

void foo(char const * fmt, ...);  // Please pass: * unsigned short
                                  //              * bool
                                  //              * char32_t
                                  //              * unsigned char

When passing arguments to a function call without parameters, i.e. matching the ellipsis, the arguments undergo default argument promotion. So far so good, but those promotions are platform dependent. I can recover the arguments with va_arg(ap, T), but what is T?

Now, for some simple situations this is easy: For example, I can always say:

unsigned short n = va_args(ap, unsigned int);

The default promotion will result in either a signed int or an unsigned int, but according to, say, C11 7.16.1.1/3, va-casting to unsigned int is always fine, since even if the default promotion results in an int, the original value can be represented by both types.

But what type should I cast to when I expect a char32_t? C++11 4.5/2 leaves the resulting type wide open. So I would like a trait that lets me write:

char32_t c = va_args(ap, default_promote<char32_t>::type);

How to do this?

Bonus points for a trait that produces a static assertion when the parameter type must not be passed as a variable argument.

3 Answers
Related