hyp*_*rum 6 c++ templates undefined-symbol variadic-templates
(最后的问题)
最近,我问了一个关于如何修复链接器错误的问题(关于模板void的多个定义的重复符号).
因为我在多个源文件中使用函数,所以我建议使用关键字inline来允许标头中的声明或将声明放在已编译的源文件中.
在我意识到inline有一些不好的反响后,我把我的声明放在一个源文件中.
现在这没关系,除了可变参数模板:
template<typename T, typename... Args>
void cleanup(T *t, Args&&... args);
Run Code Online (Sandbox Code Playgroud)
我找到了一些明显的解决方案 - 但不是变量模板 - 使用.tpp文件(但它开始再次声明重复的符号)或保留源文件并添加显式实例化.
但是void cleanup有可能使用数百种参数组合,所以我不想明确地实例化所有内容.
问题: 那么,我将如何进行
inline?.tpp声明的重复/未定义符号错误示例,并将上述模板定义分别放在源文件中.
duplicate symbol __Z7cleanupI10SDL_WindowJEEvPT_DpOT0_ in:
CMakeFiles/Game.dir/Game/main.cc.o
CMakeFiles/Game.dir/Game/RichTools/rtexture.cc.o
Run Code Online (Sandbox Code Playgroud)
_
Undefined symbols for architecture x86_64:
"void cleanup<SDL_Renderer, SDL_Window*&>(SDL_Renderer*, SDL_Window*&&&)",
referenced from:
cleanQuit() in main.cpp.o
ld: symbol(s) not found for architecture x86_64
Run Code Online (Sandbox Code Playgroud)
回答您的第一个问题的建议:进行内联或移动到源文件仅与您完全专业化的函数有关 - 这些函数具有空参数列表template <>。
所以,这样做:
你的头文件:
// This shall be in header - it is not full specialization:
template<typename T, typename... Args>
void cleanup(T *t, Args&&... args){
//Cleanup the first item in the list
cleanup(t);
//Recurse to clean up the remaining arguments
cleanup(std::forward<Args>(args)...);
}
// These shall be only declared here, and implemented in source file,
// treat fully specialized function templates as regular functions
template<>
void cleanup<SDL_Window>(SDL_Window *win);
template<>
void cleanup<SDL_Renderer>(SDL_Renderer *ren);
template<>
void cleanup<SDL_Texture>(SDL_Texture *tex);
Run Code Online (Sandbox Code Playgroud)
您的源文件:
template<>
void cleanup<SDL_Window>(SDL_Window *win){
if (!win){
return;
}
SDL_DestroyWindow(win);
}
template<>
void cleanup<SDL_Renderer>(SDL_Renderer *ren){
if (!ren){
return;
}
SDL_DestroyRenderer(ren);
}
template<>
void cleanup<SDL_Texture>(SDL_Texture *tex){
if (!tex){
return;
}
SDL_DestroyTexture(tex);
}
template<>
void cleanup<SDL_Surface>(SDL_Surface *surf){
if (!surf){
return;
}
SDL_FreeSurface(surf);
}
Run Code Online (Sandbox Code Playgroud)