Вот упрощенная, упрощенная версия работы экземпляра шаблона (я рассмотрю документацию Boost для fold ).
Скажем, вы - компилятор C ++ (давайте назовем вас clang
... это довольно крутое имя) и вы с удовольствием читаете файл .cpp
для его компиляции.Вы видите все эти нормальные функции, такие как void foo()
, float magic(int x, double p)
и int main(int argc, char** argv)
.Затем вы сталкиваетесь с чем-то вроде этого:
template <typename T>
struct is_fun
{
typedef some_other_type<T> something_else;
typedef typename something_else::value value;
}
Здесь clang
говорит: Круто, я знаю об этой структуре с именем is_fun
, которая является шаблоном с одним типом в качестве параметра.На данный момент is_fun
является неинициализированным шаблоном.Важно отметить, что здесь ничего не компилируется.Когда clang
видит шаблонное что-либо, он проверяет синтаксис (в той степени, в которой он способен) и движется дальше.Не существует способа создать неинициализированный шаблон в объектном коде - он является чисто C ++ и не скомпилирован.
Позже он приходит и видит, как is_fun
используется в таком выражении:
typedef vector<long,float,short,double,float,long,long double> types;
typedef fold<
types,
int_<0>,
if_< is_fun<_2>,next<_1>,_1 >
>
::type number_of_fun;
Теперь clang
ленив и просто говорит: «Хорошо, number_of_fun
- это просто псевдоним для этой отвратительной вещи».Еще раз, это не делает ничего.Позже в вашем коде он видит это:
int foo()
{
const int fun = number_of_fun::value;
return fun;
}
Теперь , он что-то сделал с шаблоном number_of_fun
.Теперь параметры шаблона будут заполнены значениями (потому что для этого требуется number_of_fun::value
).clang
будет проходить через все элементы Boost и, в конце концов, закончится вашим шаблонным is_fun
.Первое, что ему нужно в списке, это long
(это то, что делает свертывание вектора), поэтому он создает новый тип на основе long со всеми заполненными T
:
struct is_fun<long>
{
typedef some_other_type<long> something_else;
static const int value = typename something_else::value;
}
Этот тип будет скомпилирован, потому что он был использован.Основное правило шаблонов C ++: когда вы используете его во время компиляции, он будет создан, что означает, что он будет скомпилирован.Во время выполнения не нужно делать ничего особенного.