Создание шаблонов функций - PullRequest
3 голосов
/ 07 февраля 2020

В следующей программе мы берем адрес шаблона функции, для которого нет определения.

template <typename T>
void fun(T);

int main()
{
    void (*funptr)(int) = fun;
}

Меня учили, что компилятор решает создать экземпляр шаблона функции при получении его адреса, но вышеприведенная программа компилируется просто отлично (конечно, компоновщик выдаст ошибку, которую он не может найти для определения fun). Компиляция завершится неудачно только в том случае, если мы используем явное создание экземпляра:

template <typename T>
void fun(T);

template void fun<int>(int);

int main()
{}

Означает ли это, что только компиляция второго исходного кода создает экземпляр шаблона функции? Или это тоже в первом экземпляре, но я что-то упустил?

Заранее спасибо!

1 Ответ

6 голосов
/ 07 февраля 2020

Когда вы берете адрес или вызываете функцию, компилятор оставляет ссылку на ее создание. Если бы было определение шаблона, он был бы создан для удовлетворения этой ссылки. Но поскольку определение шаблона не предоставлено, оно не может быть фактически реализовано, поэтому остается только неразрешенная ссылка. Эта неразрешенная ссылка должна быть разрешена на этапе связывания с помощью другого объектного файла, который содержит необходимые экземпляры. Это означает, что создание экземпляра должно было произойти, когда был скомпилирован этот другой объектный файл.

Когда вы явно создаете экземпляр шаблона функции, должно присутствовать определение шаблона (в противном случае создавать нечего) , Так как вы не предоставили один, вы получите ошибку на этапе компиляции, а не ссылки.

...