Вы должны использовать extern template
, чтобы заставить компилятор not создать экземпляр шаблона, когда вы знаете , что он будет создан в другом месте. Он используется для уменьшения времени компиляции и размера объектного файла.
Например:
// header.h
template<typename T>
void ReallyBigFunction()
{
// Body
}
// source1.cpp
#include "header.h"
void something1()
{
ReallyBigFunction<int>();
}
// source2.cpp
#include "header.h"
void something2()
{
ReallyBigFunction<int>();
}
Это приведет к следующим объектным файлам:
source1.o
void something1()
void ReallyBigFunction<int>() // Compiled first time
source2.o
void something2()
void ReallyBigFunction<int>() // Compiled second time
Если оба файла связаны друг с другом, один void ReallyBigFunction<int>()
будет отброшен, что приведет к потерянному времени компиляции и размерному размеру объекта.
Чтобы не тратить время компиляции и размер объектного файла, существует ключевое слово extern
что делает компилятор не компилировать функцию шаблона. Вы должны использовать этот тогда и только тогда, когда знаете , он используется в том же двоичном файле где-то еще.
Изменение source2.cpp
на:
// source2.cpp
#include "header.h"
extern template void ReallyBigFunction<int>();
void something2()
{
ReallyBigFunction<int>();
}
В результате будут созданы следующие объектные файлы:
source1.o
void something1()
void ReallyBigFunction<int>() // compiled just one time
source2.o
void something2()
// No ReallyBigFunction<int> here because of the extern
Когда оба из них будут связаны друг с другом, второй объектный файл будет просто использовать символ из первого объектного файла. Нет необходимости отбрасывать и не тратить время на компиляцию и размер объектного файла.
Это должно использоваться только в проекте, например, когда вы используете шаблон типа vector<int>
несколько раз, вы должны использовать extern
во всех, кроме одного исходного файла.
Это также относится к классам и функциям как одна, так и даже функции членов шаблона.
Я полагаю, что проверка типа GADT всегда разрешима; это - вывод, который неразрешим, поскольку это требует объединения высшего порядка. Но средство проверки типа GADT является ограниченной формой средств проверки доказательства, которые Вы видите в, например, Coq, где конструкторы создают термин доказательства. Например, классический пример встраивания лямбда-исчисления в GADTs имеет конструктора для каждого правило сокращения, поэтому если Вы хотите найти нормальную форму термина, необходимо сказать это, какие конструкторы получат Вас к нему. Проблема остановки была перемещена в руки пользователя :-)
Вы, вероятно, уже видели это, но существует набор статей об этой проблеме при исследовании Microsoft: бумаги Проверки Типа . Первый описывает разрешимый алгоритм, на самом деле используемый в компиляторе Haskell Глазго.