昨天有對模板類的函式成員特化需求,目的是為了對不同模板引數實現不同的操作,結果在寫過程中碰到already defined的問題(貌似是模板新手最容易碰到的問題了),類外的成員函式和同在類外的特化版本成員函式衝突了。因為對模板用法不是很熟悉,找了半天發現網上一段對話:
gcc下面,判斷函式是不是內聯,是看函式實現的地方的,類裡面的函式,在gcc開啟優化的時候,會自動加上inline,如果在類裡面實現,那就可能是inline函式,如果在類外實現那就基本不會是inline(除非開o3)
普通函式我是在類裡面實現的,特化函式在類外面實現,不加inline編譯不過,說重定義了
這裡說到一點就是未特化的模板函式是放在類定義裡面用inline實現的,然後特化版本定義在外面,不然同在類外就會重定義。
問題解決!
順便記錄一下在用模板時碰到的問題以及看到的文章的摘抄:
c++ template學習筆記之函式模板確是不錯的文章,經驗性的東西的總結配合自己試著去寫,是最快的入門方式。
摘抄一些讓人有所啟發的地方:
通過將關鍵字typename引入到c++中,我們可以對模板定義進行分析。為了分析模板定義,編譯器必須能夠區分出是型別以及不是型別的表示式。如(parm代表乙個類):
template
parm minus(parm* array,u value)
編譯器不知道name是否為乙個型別,因為它只有在模板被例項化之後才能找到parm表示的類的定義。為了讓編譯器能夠分析模板定義,使用者必須指示編譯器哪些表示式是型別表示式。告訴編譯器乙個表示式是型別表示式的機制是在表示式前加上關鍵字typename。如:
template
parm minus(parm* array,u value)
顯式模板實參:
template
t min5( t, t )
// min5( unsigned int, unsigned int ) 被例項化
min5< unsigned int >( ui, 1024 );
顯式模板實參應該只被用在完全需要它們來解決二義性,或在模板實參不能被推演出來的上下文中使用模板例項時。大部分情況依賴自動解析。
模板編譯模式
一、包含編譯模式
在包含編譯模式下,我們在每個模板被例項化的檔案中包含函式模板的定義,並且往往把定義放在標頭檔案中,象內聯函式所做的那樣。如:
// model1.h
// 包含模式:模板定義放在標頭檔案中
template
type min( type t1, type t2 )
在每個使用min()例項的檔案中都包含了該標頭檔案,如:
// 在使用模板例項之前包含模板定義
#include "model1.h"
int i, j;
double dobj = min( i, j );
該標頭檔案可以被包含在許多程式文字檔案中。這意味著編譯器必須在每個呼叫該例項的檔案中例項化min()的整型例項嗎?不。該程式必須表現得好像min()的整型例項只被例項化一次。但是,真正的例項化動作發生在何時何地,要取決於具體的編譯器實現。
二、分離編譯模式
在分離編譯模式下,函式模板的宣告被放在標頭檔案中。在這種模式下,函式模板宣告和定義的組織方式與程式中的非內聯函式的宣告和定義組織方式相同。如:
// model2.h
// 分離模式:只提供模板宣告
template type min( type t1, type t2 );
// model2.c
// 模板定義
export template
type min( type t1, type t2 )
使用函式模板min()例項的程式只需在使用該例項之前包含這個標頭檔案:
// user.c
#include "model2.h"
int i, j;
double d = min( i, j ); // ok: 用法,需要乙個例項
我們通過在模板定義中的關鍵字template之前加上關鍵字export,來宣告乙個可匯出的函式模板。(在cpp檔案中定義模板函式體的方法)
三、顯式例項化宣告
標準c++提供了顯式例項化宣告來幫助程式設計師控制模板例項化發生的時間。在顯式例項化宣告中,關鍵字template後面是函式模板例項的宣告,其中顯式地指定了模板實參。下例中提供了sum(int* , int)的顯式例項化宣告:
template
type sum( type op1, int op2 ) // 函式模板sum的定義必須給出
// 顯式例項化宣告
template int* sum< int* >( int*, int );
該顯式例項化宣告要求用模板實參int*例項化模板sum()。對於給定的函式模板例項,顯式例項化宣告在乙個程式中只能出現一次。
模板函式的例項化會選擇最特化的(most specialized)模板函式,如
template
type sum( type*, int );
template
type sum( type, int );
int ia[1024];
// type==int; sum( int*, int ); or
// type==int*; sum( int*, int); ??
int ival1 = sum( ia, 1024 );
最特化的是type*版本
這裡
類模板的成員函式及類的成員模板函式的特化C
原文 今天想針對不同指標型別寫一系列處理函式,同函式過載,寫了一大堆同名的函式過載,看類宣告感覺極其醜陋。於是考慮模板及特化,測試了兩段 廢話少說,貼 例1 類模板的成員函式的特化 此處特化的是類 template class sample void sample print 呼叫 int tmai...
C 類模板的成員函式模板寫法
這幾天本來想將lua tinker移植到linux上去的,但是由於vc中的模板寫法與gcc中的模板寫法有些不同之處,比如下面一段 struct pop template static char invoke lua state l,int index template static const ch...
類模板的特化,偏特化
class templates 的特化 specializations 你可以針對某些特殊的模板引數,對乙個類模板進行特化。類模板的特化與函式模板的過載類似,使你得以針對某些特定型別進行 優化,或修正某個特定型別在函式模板具現化中的錯誤行為。然而如果你對乙個類模板進行特化,就必須特化其所有成元函式。...