在下面的最小示例中,我在Visual Studio 15.8.7(具有标准设置的标准控制台应用程序(只是删除了预编译的标头))上的本地系统上收到链接器错误:“错误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
}
增量链接在做奇怪的事情?
在wandbox上,godbolt和coliru我可以编译,链接和运行,并获得gcc和clang的预期行为。
项目要点3中描述的观察结果使我认为它与增量链接有关。但是也许代码也没有很好地定义?在学习https://en.cppreference.com/w/cpp/language/function_template时,我遇到了以下问题:
在功能上调用了两个涉及模板参数的表达式 如果它们不等价,则等价,但对于任何给定的 模板参数,两个表达式的求和结果 相同的值。
和
如果程序包含以下功能模板的声明: 在功能上等效但不等效,程序格式错误; 无需诊断。
那么,以上代码是否构成错误?我是否违反ODR?还是一切都很好,它只是一个链接程序/编译器错误?
编辑:固定点3。我在定义#2或课程中进行评论。
更新:新的一天,我想问题解决了。今天,我无法重现问题。我没有更改系统上的任何内容。我刚启动,打开了我的项目,它按预期运行。不知道发生了什么事。但与学习新的特殊奥秘模板重载规则:-P
相比,这种方法更好答案 0 :(得分:2)
该程序很好。您有两个被调用的不同函数。这是编译器和/或链接器错误。
可以重载功能模板,以便两个不同的功能模板专长具有相同的类型。
[示例:
$Body = @" <html> <body style="font-family:calibri"> <b>This is image 1</b> <img src='cid:TEST1.png'> <b>This is image 2</b> <img src='cid:Test2.png'> </body> </html> "@ Send-MailMessage -To "Test@Test.com" ` -from "Test2@Test.com" ` -SmtpServer Test.smtp.com ` -Subject "Hello" ` -BodyAsHtml -body $body ` -Attachments "C:\Test\TEST1.png", "C:\Test\TEST2.png"
-举个例子]
此类专业化是不同的功能,并且不违反一定义规则。
您有两个不同的功能模板,即句号。关于等价的措辞与模板参数和相关表达式([temp.over.link]/5)有关:
如果[...]
,则包含模板参数的两个表达式被认为是等效的。
// 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*)
}
不包含模板参数,因此绝不等同于int
。