Variadic Templates – Transformations!

Wow, I just accidentally exposed another feature of Variadic Templates – you can transform them, and then create a new Variadic Template on-the-fly!  This is so cool!

Let me explain:

Given this call to TestVariadic:

  TestVariadic(0, 4, 'a', '\0', p, 0, "string");

and given this function:

template <typename... Args>
void TestVariadic(const Args&... args)
{
    std::cout << "vals (in reverse):" << std::endl;
    bool_variadic(boolizer(args)...);
}

We call (for each argument) ‘boolizer()’, which does nothing but return a true/false boolean value:

template <typename T>
bool boolizer(const T& val)
{
    std::cout <<  val << "	";
    return (val != 0);
}

Nothing fancy eh?  And note we’re working in reverse-order again (see my edit on last post), so we’ll see the list printed out right-to-left.  However, the cool thing is – we call a ‘bool_variadic()’ function with the return values from boolizer().  And this ain’t no ‘dummy()’ function.. it’s special =).  Here it is:

template <typename... Args>
void bool_variadic(const Args&... args)
{
    std::cout << "\nbool states (in FORWARD order):\n" << std::boolalpha;
    //dummy(reportBoolState(args)...);  // this'd be reverse order (right-to-left)
    reportBoolState(args...);
    std::cout << std::endl;
}

Okay, I know – more variadic template functions – annoying!!  But check it out – ‘reportBoolState()’ is a templated recursive function (well, not such a new thing), that ONLY operates on bool values (now we’re getting somewhere).  So here’s the two necessary functions required of any recursive variadic template design (non-variadic overload before the main val+variadic recursive func):

int reportBoolState(bool bVal)
{
    std::cout << bVal << "	";
    return 0;
}

template <typename... Args>
int reportBoolState(bool bVal, const Args&... args)
{
    std::cout << bVal << "	";
    reportBoolState(args...);
    return 0;
}

So, take a moment to gather this in.. We’ve literally transformed a set of varying types (that’d be the Args pack) into something completely different – a simple list of booleans!  That’s just awesome!  Oh.. and note that with the recursive variadic functions, we do actually move left-to-right, so the booleans are in the same order as the original variadic template list.(this is why the output doesn’t match up).  You could uncomment that ‘dummy’ line to see things in right-to-left order, however.  Man, this stuff is funn =)

Oh, and here’s the full example from above at Coliru’s online compiler.  Also available on Pastebin.com.

P.S. initializer_list’s are one of my other favorite new features – but quite limited in they only accept a compile-time-defined list of one type, and can’t be used dynamically with, say, a boolean list of variadic templates.. =P  (it’d be cool if someone proved me wrong though)

Advertisements

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s