Your code shows three new C++11 features: variadic templates, user-defined literals and static assertions.
The general variadic class template specifies zero or more arguments, the specialized versions one or more, and exactly one, respectively.
// digits can be the empty set, so 0 or more arguments
template<char... digits>
struct conv2bin;
// digits can be the empty set, so 1 or more arguments
template<char high, char... digits>
struct conv2bin<high, digits...>
// fully specialized for 1 argument
template<char high>
struct conv2bin<high>
The full syntax of variadic templates is a bit quirky, Wikipedia has a decent article on it. It is especially useful for another C++11 feature: perfect forwarding of a variadic number of function arguments.
The exotic looking int operator "" _b()
defines a user-defined literal, which is a way to add your own units to your types and expression. It simply means that integers followed by _b
are tagged with a certain "unit". See this question for more details. One practical benefit would be to avoid future Mars lander crashes (where SI and imperial units were being mixed in their landing software, without the compiler being able to diagnose it).
The static_assert
does exactly what you think it does: it asserts its condition statically, i.e. at compile-time. When the assertion fails, compilation is halted. This is a great way to detect errors as soon as possible.
UPDATE
Specialization of variadic templates can be very surprising when you have partially overlapping ranges of arguments: the zero or more arguments version will only match an empty list in your example (in case you would have provided a definition for it).
#include <iostream>
template<int... Args>
struct Test
{
enum { value = 0 };
};
template<int I, int... Args>
struct Test<I, Args...>
{
enum { value = 2 };
};
template<int I>
struct Test<I>
{
enum { value = 1 };
};
int main()
{
std::cout << Test<>::value << "\n"; // matches zero or more version
std::cout << Test<0>::value << "\n"; // matches single argument version
std::cout << Test<0, 0>::value << "\n"; // matches one or more version, not the zero or more one!
}
Output on LiveWorkSpace.
This is of course an example of the general rule for partial template specialization which states that the most specialized version will be selected (one-or-more is more specialized than zero-or-more, since the latter can always be used where the former can, but not vice versa). But because variadic templates are often not so "visibly" different from each other, you should be extra careful with their partial specializations.