假设一个头文件定义了一个函数模板。现在假设#include
这个头文件有两个实现文件,每个都有一个函数模板的调用。在两个实现文件中,函数模板都使用相同的类型进行实例化。
// header.hh
template <typename T>
void f(const T& o)
{
// ...
}
// impl1.cc
#include "header.hh"
void fimpl1()
{
f(42);
}
// impl2.cc
#include "header.hh"
void fimpl2()
{
f(24);
}
人们可能期望链接器会抱怨f()
. 具体来说,如果f()
不是模板,那么情况确实如此。
- 为什么链接器不抱怨多个定义
f()
? - 标准中是否规定链接器必须优雅地处理这种情况?换句话说,我可以总是指望类似于上面的程序来编译和链接吗?
- 如果链接器可以足够聪明地消除一组函数模板实例化的歧义,为什么它不能对常规函数做同样的事情,因为它们与实例化函数模板的情况相同?