C++ 函数模板的显式专门化导致链接器错误
职能.h:C++ 函数模板的显式专门化导致链接器错误,c++,templates,template-specialization,C++,Templates,Template Specialization,职能.h: #pragma once #include <iostream> template<class T> void TemplatedFunction(T* p) {} template<> void TemplatedFunction<float>(float* p) {} template<> void TemplatedFunction<char>(char* p) {} 生成错误: main.obj
#pragma once
#include <iostream>
template<class T> void TemplatedFunction(T* p) {}
template<> void TemplatedFunction<float>(float* p) {}
template<> void TemplatedFunction<char>(char* p) {}
生成错误:
main.obj : error LNK2005: "void __cdecl TemplatedFunction<float>(float *)" (??$TemplatedFunction@M@@YAXPAM@Z) already defined in Functions.obj
main.obj : error LNK2005: "void __cdecl TemplatedFunction<char>(char *)" (??$TemplatedFunction@D@@YAXPAD@Z) already defined in Functions.obj
main.obj:错误LNK2005:“void u cdecl TemplatedFunction(float*)”(?)$TemplatedFunction@M@@YAXPAM@Z)已在Functions.obj中定义
main.obj:错误LNK2005:“void u cdecl TemplatedFunction(char*)”(??)$TemplatedFunction@D@@YAXPAD@Z)已在Functions.obj中定义
我知道两种解决方法:
静态
。但这意味着在包含函数.h的所有.cpp文件中都会出现专用函数,即使没有使用它们,这可能会导致代码重复静态声明的情况下,是否有其他解决方案来防止链接器错误?如果函数被声明为“代码> static < /Cord>”,那么现代C++编译器是否将它们从优化的构建中移除,如果没有使用它们?
编辑。
在阅读了前两个答案后:我不想在这里问如何防止这种链接器错误。假设我无法将专用化移动到.cpp文件,并将其保留在.h文件中,使用static
或inline
,当这些函数添加到包含.h文件的每个.cpp文件中时,即使未使用它们,这是否会导致优化构建中的代码重复和膨胀
所以,我看到专门的模板化函数的行为类似于非模板化函数
对
没有静态声明的情况下,是否有其他解决方案来防止链接器错误
是,与任何正常的非模板函数一样:
将函数专门化定义为inline
或声明(但不定义)标题中的专门化:
template<> void TemplatedFunction<float>(float* p);
template<> void TemplatedFunction<char>(char* p);
这些选项比使用static
更好,因为使函数静态还有其他副作用,例如在每个翻译单元中为函数指定不同的地址,以及在每个翻译单元中使局部静态变量不同。这是一个语义变化,而不仅仅是链接器错误的解决方案
如果函数被声明为代码> static < /C>,如果没有使用,现代C++编译器会从优化的构建中移除它们吗?< /P>
对。但是在使用它们的任何文件中,都会得到重复的代码,这使得可执行文件比函数只有一个定义时更大
假设我无法将专用化移到.cpp文件中,并将其保留在.h文件中,并带有静态
我看不出有什么必要这么做的理由,但无论如何
。。。或者inline
,如果将这些函数添加到包含.h文件的每个.cpp文件中(即使未使用),是否会导致优化版本中的代码重复和膨胀
不,如果它们未在给定文件中使用,则不会影响从该文件编译的对象的大小
您的问题具有误导性,因为它似乎是关于模板的(标题显然是关于模板的!),但未使用的内联/静态函数是否会导致代码膨胀与函数是否为模板无关
如果您的问题只是“未使用的内联函数和静态函数是否会影响对象大小?”那么对于普通函数和函数模板,答案都是否定的。此类明确的专业化应移到.cpp文件中,或使其成为内联的。链接器将在那里找到它们。如果在标头中定义它们,您将获得“已定义”错误消息,就像在由多个编译单元包含的标头中定义的普通非内联和非静态函数中获得错误消息一样。显式专门化的主体需要放入cpp文件中,就像普通的非模板函数一样(这就是它们)。如果愿意,您可以交替使用inline
标记它们(这很有意义)。谢谢,但我问题的重点是:如果函数保留在.h文件中,这是否会导致优化版本中的代码膨胀?请参阅我编辑的问题。如果您使它们内联
,请将这些专门化视为常规内联函数。通常,它们不应导致任何代码膨胀,但与常规内联一样,有时t可能值得检查,例如,将它们临时内联到.cpp并比较可执行文件的大小。谢谢,比较可执行文件的大小是个好主意,我会这样做。
main.obj : error LNK2005: "void __cdecl TemplatedFunction<float>(float *)" (??$TemplatedFunction@M@@YAXPAM@Z) already defined in Functions.obj
main.obj : error LNK2005: "void __cdecl TemplatedFunction<char>(char *)" (??$TemplatedFunction@D@@YAXPAD@Z) already defined in Functions.obj
template<> void TemplatedFunction<float>(float* p);
template<> void TemplatedFunction<char>(char* p);
template<> void TemplatedFunction<float>(float* p) {}
template<> void TemplatedFunction<char>(char* p) {}