使用以下最小示例,我在 visual studio 15.8.7(具有标准设置的标准控制台应用程序(仅删除预编译 header ))中的本地系统上出现链接器错误:“错误 LNK1179 文件无效或损坏:COMDAT 重复? ?$f@H@@YAXH@Z'"
#include <cstdio>
template<typename T> void f(T) { printf("1"); } //#1. T can be deduced
template<typename T> void f(int) { printf("2"); } // #2. T needs to be specified explicitly
int main()
{
f(8); // a) calls #1
f<int>(8); // b) calls #2
}
- 注释掉调用 a) 或调用 b) 将导致成功链接。独立调用 a) 调用模板定义#1。第二次调用 b) 调用模板定义#2。正如预期的那样。
- 在 Release模式下构建成功。输出为 11。因此两个调用都调用模板定义 #1。意外。 ODR 违规?
- 此外,我观察到以下奇怪的行为(在调试设置中):
- 我注释掉模板定义#2
- 我做了一个完整的重建
- 我在模板定义 #2 中回复
- 我构建(不是重建,只是构建)
- 构建成功
- 输出是 11 而不是 12
增量链接做奇怪的事情?
在 wandbox、godbolt 和 coliru 上,我可以使用 gcc 和 clang 编译、链接和运行并获得预期的行为。
要点 3 中描述的观察结果让我认为它与增量链接有关。但也许代码也没有明确定义?学习的时候https://en.cppreference.com/w/cpp/language/function_template我遇到了以下情况:
Two expressions involving template parameters are called functionally equivalent if they are not equivalent, but for any given set of template arguments, the evaluation of the two expressions results in the same value.
和
If a program contains declarations of function templates that are functionally equivalent but not equivalent, the program is ill-formed; no diagnostic is required.
那么,上面的代码是不是格式错误?我有 ODR 违规吗?或者一切都很好,只是链接器/编译器错误?
编辑:固定点 3。我在定义 #2 或类(class)中回复评论。
更新:新的一天,我想问题已经解决了。今天我无法重现这个问题。我没有更改系统上的任何内容。我刚启动,打开我的项目,它按预期工作。不知道怎么回事。但与学习新的特殊奥术模板重载规则相比,这种方式更好:-P
最佳答案
程序很好。您有两个正在调用的不同 函数。这是编译器和/或链接器错误。
It is possible to overload function templates so that two different function template specializations have the same type.
[ Example:
// translation unit 1: template<class T> void f(T*); void g(int* p) { f(p); // calls f<int>(int*) } // translation unit 2: template<class T> void f(T); void h(int* p) { f(p); // calls f<int*>(int*) }
— end example ]
Such specializations are distinct functions and do not violate the one-definition rule.
你有两个不同的功能模板,句号。关于等价的措辞与模板参数和依赖表达式有关([temp.over.link]/5):
Two expressions involving template parameters are considered equivalent if [...]
int
不涉及模板参数,因此不能认为它等同于 T
。
关于c++ - 模板重载导致链接器错误/奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52838159/