【发布时间】:2015-07-11 01:42:22
【问题描述】:
(最后的问题在底部)
最近,我向 a question 询问了我将如何修复链接器错误(关于与模板 void 的多个定义有关的重复符号。
因为我在多个源文件中使用了函数,所以建议我使用关键字inline 来允许在头文件中声明或将声明放在已编译的源文件中。
在我意识到inline 有一些不好的影响后,我将我的声明放在了一个源文件中。
现在这没问题了,除了可变参数模板:
template<typename T, typename... Args>
void cleanup(T *t, Args&&... args);
我找到了一些明显的解决方案 - 但不是可变参数模板 - 使用 .tpp 文件(但它再次开始声明重复符号)或保留源文件并添加显式实例化。
但是void cleanup 有可能使用数百种参数组合,所以我不想显式实例化所有内容。
问题: 那么,我该怎么做呢
- 将可变参数模板定义保留在源文件中,或者
- 将定义放入 .tpp 文件中不会出现重复符号,最终避免使用
inline?
.tpp 声明的重复/未定义符号错误示例并将上述模板定义分别放在源文件中。
duplicate symbol __Z7cleanupI10SDL_WindowJEEvPT_DpOT0_ in:
CMakeFiles/Game.dir/Game/main.cc.o
CMakeFiles/Game.dir/Game/RichTools/rtexture.cc.o
_
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
【问题讨论】:
-
您希望编译器在使用时生成实例化,但又想自动丢弃重复项?那就用
inline吧!您提到您考虑过使用它,但它有“不良影响”,但究竟是什么? -
似乎在您的第一个问题中您没有理解答案。进行内联或移至源文件的建议仅与您完全专业化的功能有关-这些带有空参数列表模板。
标签: c++ templates variadic-templates undefined-symbol