Ваш код показывает три новые функции C++ 11: VARIADIC шаблоны, пользовательские литералы и статические утверждения.
Общий шаблон вариационного класса указывает ноль или более аргументов, специализированные версии одного или нескольких и ровно один, соответственно.
// 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>
Полный синтаксис шаблонов переменного числа битого изворотливый, Wikipedia имеет приличную статью о нем. Это особенно полезно для другой функции C++ 11: совершенная переадресация вариационного числа аргументов функции.
Экзотический вид int operator "" _b()
определяет определяемый пользователем литерал, который позволяет добавлять собственные единицы к вашим типам и выражениям. Это просто означает, что целые числа, за которыми следуют _b
, помечены определенной «единицей». См. Это question для более подробной информации. Одно практическое преимущество заключалось бы в том, чтобы избежать будущих сбоев приземления на Марсе (где СИ и имперские подразделения смешивались в своем программном обеспечении для посадки, без возможности компилятора его диагностировать).
static_assert
выполняет то, что вы думаете, что он делает: он утверждает свое состояние статически, то есть на время компиляции. Когда утверждение не выполняется, компиляция прекращается. Это отличный способ обнаружить ошибки как можно скорее.
UPDATE
Специализация переменным числом шаблонов может быть очень удивительно, если у вас есть частично перекрывающиеся диапазоны аргументов: версия ноль или более аргументов соответствует только пустой список в вашем примере (в случае, если бы дали для нее определение).
#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!
}
Выход на LiveWorkSpace.
Это, конечно, пример общего правила для частичной специализированности шаблонов, в котором указывается, что будет выбрана самая специализированная версия (одна или более более специализированная, чем нуль или больше, всегда можно использовать там, где первый может, но не наоборот). Но поскольку вариативные шаблоны часто не так «заметно» отличаются друг от друга, вы должны быть осторожны с их частичными специализациями.
Да, извините за ошибку – Paul
Взгляните на эти ссылки. Они должны все объяснить. - [Шаблоны Variadic] (http://www.cplusplus.com/articles/EhvU7k9E/) - [Пользовательские литералы] (http://en.cppreference.com/w/cpp/language/user_literal) - [Статические Утверждение] (http://en.cppreference.com/w/cpp/language/static_assert) –