Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
759 views
in Technique[技术] by (71.8m points)

c++ - Explicit specialization of function templates causes linker error

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:

#include "Functions.h"

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

main.cpp:

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

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

Build errors:

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. 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.

  2. 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.

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?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

Correct.

Is there any other solution to prevent linker error without static declaration?

Yes, like any normal non-template function:

Either Define the function specializations as inline

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

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

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

and define them in Functions.cpp

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

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

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.

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.

Assuming that I cannot move specialization to .cpp file and leave it in .h file with static ...

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

... 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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...