C++ 函数模板特化导致的多重定义链接错误
生活随笔
收集整理的這篇文章主要介紹了
C++ 函数模板特化导致的多重定义链接错误
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
轉載請注明文章:C++ 函數模板特化導致的多重定義鏈接錯誤 出處:多客博圖
標題說的可能不是很清楚,解釋一下,函數模板,一般都是放在頭文件里面,所以有些時候,我也會做一個特化,也放在這個頭文件里面,當這個頭文件出現多次的包含之后,就會出現鏈接多重定義的錯誤,先說一個例子,如下:
現象描述
有文件"header.h"
#ifndef HEADER #define HEADERtemplate <class T> size_t size_rb_tree_node() {return 20; /*constant value for l r p pointer and (color & height) and void * value*/ }template <> size_t size_rb_tree_node<void *>() {return 30; }#endif"Source.cpp"
#include "Header.h"int count() {int a = size_rb_tree_node<int>();return a; }?"main.cpp"
#include "Header.h"using namespace std;int count();int main() {int a = size_rb_tree_node<int>();a = size_rb_tree_node<void *>(); }編譯后,在鏈接的時候報錯了:
1>------ Build started: Project: Win32Project1, Configuration: Debug Win32 ------ 1> AllocatorNew.cpp 1>Source.obj : error LNK2005: "unsigned int __cdecl size_rb_tree_node<void *>(void)" (??$size_rb_tree_node@PAX@@YAIXZ) already defined in AllocatorNew.obj 1>C:\Users\tianzuoz\Documents\Visual Studio 2012\Projects\Win32Project1\Debug\Win32Project1.exe : fatal error LNK1169: one or more multiply defined symbols found ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========其實原因很簡單了,因為特化后的函數就是一個普通函數,這個和在一個頭文件里面定義一個函數,然后多出include這個頭文件一樣的結果,都會導致多重定義。
解決方法
1、把特化的函數,添加inline標記,這樣,編譯器不會給這個函數生成一個函數符號,就當作是一個宏展開吧,不過,有些編譯器不一定會inline的。行不行試試就知道了,如下:
#ifndef HEADER #define HEADERtemplate <class T> size_t size_rb_tree_node() {return 20; /*constant value for l r p pointer and (color & height) and void * value*/ }template <> inline size_t size_rb_tree_node<void *>() {return 30; }#endif2、讓這個函數成為文件域,也就是不參與全局link,也是可以的:
#ifndef HEADER #define HEADERtemplate <class T> size_t size_rb_tree_node() {return 20; /*constant value for l r p pointer and (color & height) and void * value*/ }template <> static size_t size_rb_tree_node<void *>() {return 30; }#endif3、還有一個辦法就是,把這個特化從頭文件里面拿出去,放在需要的實現文件里面,再添加static屬性。
總結
以上是生活随笔為你收集整理的C++ 函数模板特化导致的多重定义链接错误的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++输入输出运算符重载(“”“”)
- 下一篇: s3c2440移植MQTT