想象一下,我们有两个使用std::vector
的不同实现构建的静态库。这两个二进制文件都有push_back
和pop_back
的代码(因为向量通常只是标题)。当我们尝试在项目中使用这两个库时,链接器会做什么。它会出错吗?链接器是否可以删除每个方法的一个实现,以便可以执行以下操作:
push_back
调用从第一个库调用push_back
实现
pop_back
调用从第二个库调用pop_back
实现
答案 0 :(得分:3)
会出错吗?取决于你如何定义“错误”。
在链接时可能不会给你一个错误。但它肯定会破坏你的可执行文件。链接器在遇到符号的多个定义时假设它们是相同的,因此除了其中一个之外的其他所有都可以被丢弃。如果它们不相同,那么你违反了单一定义规则,这意味着你正在进入未定义的行为领域。什么都可能发生。最有可能的是,你会看到随机崩溃。
答案 1 :(得分:1)
编译系统为模板采用的最常见(但不是唯一)方法是编译器贪婪地实例化每个转换单元中使用的所有模板,从而导致多个实例化。然后链接器以静默方式丢弃重复项。
但是,我肯定不会依赖这种行为来处理同一(命名)模板的两种不同实现。
答案 2 :(得分:1)
最有可能的是,两种实现中的一种将被选择用于外部呼叫。
因为这里有很多陷阱我不会尝试这样做。这是一些问题:
答案 3 :(得分:0)
根据链接者的心情,你最终会调用一个或另一个。一个糟糕的情况。