C 函式模板特化導致的多重定義鏈結錯誤

2021-08-13 09:45:16 字數 1692 閱讀 2196

標題說的可能不是很清楚,解釋一下,函式模板,一般都是放在標頭檔案裡面,所以有些時候,我也會做乙個特化,也放在這個標頭檔案裡面,當這個標頭檔案出現多次的包含之後,就會出現鏈結多重定義的錯誤,先說乙個例子,如下:

有檔案"header.h"

#ifndef header

#define header

template size_t size_rb_tree_node()

template <>

size_t size_rb_tree_node()

#endif

"source.cpp"

#include "header.h"

int count()

"main.cpp"

#include "header.h"

using namespace std;

int count();

int main()

1>------ build started: project: win32project1, configuration: debug win32 ------

1> allocatornew.cpp

1>source.obj : error lnk2005: "unsigned int __cdecl size_rb_tree_node(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 header

template size_t size_rb_tree_node()

template <>

inline size_t size_rb_tree_node()

#endif

2、讓這個函式成為檔案域,也就是不參與全域性link,也是可以的:

#ifndef header

#define header

template size_t size_rb_tree_node()

template <>

static size_t size_rb_tree_node()

#endif

3、還有乙個辦法就是,把這個特化從頭檔案裡面拿出去,放在需要的實現檔案裡面,再新增static屬性。

函式模板的特化

函式模板的特化 該定義中乙個或多個模板形參的實際型別或實際值是指定的。特化形式如下 關鍵字template後面接一對空的尖括號 再接模板名和一對尖括號,及括號中指定這個特化定義的模板形參 函式形參表 函式體 template int compare const char const v1,const...

函式模板的特化

include include using namespace std 泛型版本 template int compare const t v1,const t v2 為實參型別 const char 提供特化版本 template int compare const char const v1,c...

函式模板「偏特化」 (C )

模板是c 中很重要的乙個特性,利用模板可以編寫出型別無關的通用 極大的減少了 量,提公升工作效率。c 中包含類模板 函式模板,對於需要特殊處理的型別,可以通過特化的方式來實現特定型別的特殊操作。最近工作中,需要處理cont這種復合型別和t這種自定義型別的模板特化,因為cont型別有五種左右需要特殊處...