函数模板的显式特化导致链接器错误 [英] Explicit specialization of function templates causes linker error

查看:203
本文介绍了函数模板的显式特化导致链接器错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Functions.h:

Functions.h:

#pragma once
#include <iostream>

template<class T> void TemplatedFunction(T* p) {}

template<> void TemplatedFunction<float>(float* p) {}

template<> void TemplatedFunction<char>(char* p) {}

Functions.cpp:

Functions.cpp:

#include "Functions.h"

void Test()
{
    TemplatedFunction<float>(NULL);
    TemplatedFunction<char>(NULL);
}

main.cpp:

#include "Functions.h"
void Test();

int main()
{
    Test();
    return 0;
}

生成错误:

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

我知道两种方法来解决这个问题:

I know two ways to fix this:


  1. 不要将函数.h包含到多个.cpp文件中 - 如果h文件包含许多.cpp文件中需要的其他定义,则无法应用于复杂项目。

  1. Don't include Functions.h to several .cpp files - cannot be applied in complicated project, if h-file contains some additional definitions needed in many .cpp files.

将所有模板函数声明为 static 。但这意味着,包含函数.h的所有.cpp文件中都会出现专门的函数,即使它们未被使用,也可能导致代码重复。

Declare all templated functions as static. But this means that specialized functions appear in all .cpp files where Functions.h is included, even if they are not used, which possibly causes code duplication.

所以,我看到专门的模板函数行为像非模板函数。是否有任何其他解决方案来防止链接器错误,而没有 static 声明?如果函数声明为 static ,现代C ++编译器是否从优化版本中删除它们(如果不使用它们)?

So, I see that specialized templated function behaves like non-templated function. Is there any other solution to prevent linker error without static declaration? If functions are declared static, does modern C++ compiler remove them from optimized build, if they are not used?

编辑。
阅读前两个答案后:我不问这里如何防止这种链接器错误。假设我不能移动专业化到.cpp文件,并保留在.h文件与 static inline 当这些函数被添加到每个包含.h文件的.cpp文件时,即使它们未被使用,也会导致代码重复和膨胀在优化构建中。

Edit. After reading first two answers: I don't ask here how to prevent such linker error. Assuming that I cannot move specialization to .cpp file and leave it in .h file with static or inline, does this cause code duplication and bloating in optimized build, when these functions are added to every .cpp file where .h file is included, even if they are not used?

推荐答案


所以,我看到专门的模板函数的行为像非模板函数。

So, I see that specialized templated function behaves like non-templated function.

正确。


是否有任何其他解决方案可防止链接器错误 static 声明?

是的,与任何正常的非模板函数一样:

Yes, like any normal non-template function:

将功能定义为 inline

声明(但不定义)标题中的特殊化:

or Declare (but do not define) the specializations in the header:

template<> void TemplatedFunction<float>(float* p);

template<> void TemplatedFunction<char>(char* p);

并在 Functions.cpp / p>

and define them in Functions.cpp

template<> void TemplatedFunction<float>(float* p) {}

template<> void TemplatedFunction<char>(char* p) {}

$ c> static ,因为使得函数静态具有其他副作用,例如在每个翻译单元中给予不同地址的函数,并且使得每个翻译单元中的局部静态变量不同。这是一个语义上的变化,而不只是链接器错误的解决方案。

These are better options than using static, because making the functions static has other side effects, such as giving the functions different addresses in each translation unit, and making local static variables different in every translation unit. That's a semantic change, not just a solution to the linker error.


如果函数声明 static ,现代C ++编译器是否从优化版本中删除它们,如果他们不使用?

If functions are declared static, does modern C++ compiler remove them from optimized build, if they are not used?

但是在任何使用它们的文件中,你会得到重复的代码,使得可执行文件比函数的单个定义更大。

Yes. But in any files where they are used, you will get duplicate code, making the executable larger than if there was a single definition of the function.


假设我不能将专业化移动到.cpp文件,并保留在.h文件中 static ...

我看不出有什么好的理由为什么这是必要的,但无论如何...

I can't see any good reason why that would be necessary, but anyway ...


...或 inline ,这会导致代码重复和膨胀在优化构建,当这些功能添加到每个.cpp文件,其中包含.h文件,即使它们不被使用?

... or inline, does this cause code duplication and bloating in optimized build, when these functions are added to every .cpp file where .h file is included, even if they are not used?

不,如果它们不在给定文件中使用,它们不会影响编译对象的大小

No, if they are not used in a given file they will not affect the size of the object compiled from that file.

您的问题是误导性的,因为它似乎是关于模板(标题非常清楚地关于模板!),但是未使用的内联/静态函数导致代码膨胀是而不管函数是否是模板。

Your question is misleading because it appears to be about templates (the title is very clearly about templates!) but whether unused inline/static functions cause code bloat is independent of whether the functions are templates or not.

如果你的问题是do unused inline and static functions影响对象大小?答案是否定的,对于正常功能和功能模板。

If your question is simply "do unused inline and static functions affect object size?" the answer is no, for both normal functions and function templates.

这篇关于函数模板的显式特化导致链接器错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆