在下面的程序中,我们获取没有可用定义的功能模板的地址。
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()
{}
这是否意味着仅编译第二个源代码才能实例化功能模板?还是在第一个实例中也实例化了,但是我缺少了什么?
谢谢!
答案 0 :(得分:6)
当您获取地址或调用函数时,编译器将保留对其实例化的引用。如果有模板定义,它将被实例化以满足该引用。但是,由于未提供模板定义,因此无法实际实例化,因此只剩下未解析的引用。该未解析的引用必须在链接阶段由另一个包含必需实例化的目标文件来解析。这意味着实例化必须在编译另一个目标文件时发生。
显式实例化函数模板时,模板定义为must be present(否则,没有任何实例化)。由于尚未提供,因此在编译阶段会出错,而不是链接。