Did you pack that yourself?

5 11 2011

A while ago I answered a stackoverflow question related to C++11’s variadic templates. I gave an example of one of the simplest variadic template functions imaginable:

int maximum(int n)
    return n;

template<typename... Args>
int maximum(int n, Args... rest)
    return max(n, maximum(rest...));

A commenter asked if the ellipsis after Args and rest have any meaning or are they just syntactic salt?

This is a good question, the trailing ellipsis are used to expand the template parameter pack but since the only thing[1] you can do with a parameter pack (or pattern) is expand it, why do we need the extra syntax?

I didn’t know the answer at first but after a bit of thought I believe this is the rationale:

When you unpack a template pack the compiler conceptually writes out the expanded pack, so if rest is { -2, 3, -4 } the compiler turns maximum(rest...); into maximum(-2, 3, -4);  but you can do more, if you want to find the maximum of the absolute value of the numbers you could write maximum(abs(rest)...) (note the ellipsis come after the close paren) which would expand to maximum(abs(-2), abs(3), abs(-4)). The location of the ellipsis matters that’s why you have to write it explicitly.

This is also true with the template patterns.

template <typename... Pack>
struct united : std::tuple<Pack...> {

united<const char*, int, bool> we_stand;
// we_stand is equivalent to being of type:
// struct united_XYZ : std::tuple {};

std::tuple<const char*, int, bool> *ok = &we_stand;
std::tuple<bool> *error = &we_stand; 

template <typename... Pack>
struct divided : std::tuple<Pack>... {

divided<const char*, int, bool> we_fall;
// we_fall is equivalent to being of type:
// struct divided_XYZ : std::tuple, std::tuple, std::tuple {};

std::tuple<bool>*ok =&we_fall;
std::tuple<const char*,int,bool>*error =&we_fall;

[1] And call sizeof… on it but that’s just nitpicking. 




One response

15 11 2011
Assaf Lavie

Great post. Thanks!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: