Компилятор будет генерировать код для каждого экземпляра шаблона при использовании шаблона во время этапа компиляции. В процессе компиляции и компоновки файлы .cpp преобразуются в чистый объектный или машинный код, который в них содержит ссылки или неопределенные символы, поскольку файлы .h, которые включены в ваш main.cpp, не имеют реализации YET. Они готовы быть связаны с другим объектным файлом, который определяет реализацию для вашего шаблона, и, следовательно, у вас есть полный исполняемый файл a.out. Однако, поскольку шаблоны необходимо обрабатывать на этапе компиляции, чтобы сгенерировать код для каждого экземпляра шаблона, который вы делаете в своей основной программе, ссылка не поможет, поскольку компиляция main.cpp в main.o, а затем компиляция вашего шаблона .cpp в template.o, а затем ссылка не будет достигать цели шаблонов, потому что я связываю различные экземпляры шаблонов с одной и той же реализацией шаблона! И шаблоны должны делать обратное, т. Е. Иметь одну реализацию, но допускать много доступных экземпляров посредством использования одного класса.
Значение typename T
get заменяется во время этапа компиляции, а не на этапе связывания, поэтому, если я попытаюсь для компиляции шаблона без замены T
в качестве конкретного типа значения, чтобы он не работал, потому что это определение шаблонов - это процесс времени компиляции, а мета-программирование btw - все об использовании этого определения.
Это похоже на компиляцию, но это очень уродливо. Есть ли способ упростить это?
enum Foo<'a> {
Foo1(Option<&'a mut Foo<'a>>),
Foo2(i16),
}
impl<'a> Foo<'a> {
fn bar(&'a mut self, y: i16) -> (i16, &'a mut Foo<'a>) {
match (&mut *self, y) {
(Foo::Foo1(Some(ref mut a)), b) if (b == 5) => {
return a.bar(y)
},
(self2, c) => {
let n = match (&mut *self2 , c) {
(Foo::Foo2(ref mut a), b) if (b == 5) => {
print!("is five");
*a = (b + 42) as i16;
*a * b
},
ref mut x => {
print!("is not five!");
y
}
};
return (n, self2)
}
}
}
}