Fundeps и GADTs: Когда тип проверяет разрешимый?

Вы должны использовать 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 во всех, кроме одного исходного файла.

Это также относится к классам и функциям как одна, так и даже функции членов шаблона.

16
задан Don Stewart 27 April 2011 в 21:17
поделиться

2 ответа

Я полагаю, что проверка типа GADT всегда разрешима; это - вывод, который неразрешим, поскольку это требует объединения высшего порядка. Но средство проверки типа GADT является ограниченной формой средств проверки доказательства, которые Вы видите в, например, Coq, где конструкторы создают термин доказательства. Например, классический пример встраивания лямбда-исчисления в GADTs имеет конструктора для каждого правило сокращения, поэтому если Вы хотите найти нормальную форму термина, необходимо сказать это, какие конструкторы получат Вас к нему. Проблема остановки была перемещена в руки пользователя :-)

8
ответ дан 30 November 2019 в 23:18
поделиться

Вы, вероятно, уже видели это, но существует набор статей об этой проблеме при исследовании Microsoft: бумаги Проверки Типа . Первый описывает разрешимый алгоритм, на самом деле используемый в компиляторе Haskell Глазго.

1
ответ дан 30 November 2019 в 23:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: