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

2022-07-05 10:42:08 字數 2108 閱讀 9985

模板是c++中很重要的乙個特性,利用模板可以編寫出型別無關的通用**,極大的減少了**量,提公升工作效率。c++中包含類模板、函式模板,對於需要特殊處理的型別,可以通過特化的方式來實現特定型別的特殊操作。

最近工作中,需要處理cont這種復合型別和t這種自定義型別的模板特化,因為cont型別有五種左右需要特殊處理,其餘的可以用預設處理函式,type的具體型別有上千種,但是type型別不涉及不同的操作。

方案一:採用兩個模板引數

template typename cont>

void func(const cont&v) {}

//或template void func(const t &v) {}

問題:由於c++不支援模板函式偏特化,實際特化的時候會退化的第二個的情形,即需要手動編寫幾千個函式來實現特化,這種方法不可接受。

方案二:採用偏特化類模板的第二個模板引數

templatetypename cont>

struct my_class

};//將cont偏特化為vector

template struct my_class

};

問題:首先,這種形式的偏特化可以實現復合型別的需求,但是對於使用者自定義型別無法相容

方案三:利用sfinae控制模板函式例項化實現「偏特化」 (示例**部分使用c++17語法)

//

「偏特化」vector容器型別的模板函式

template typename cont>

void func(const cont&v, std::enable_if_t::value && std::is_same_vint>, cont>> * =nullptr)

{}//

如果使用c++11版本的gcc時,偏特化vector等標準容器型別的模板函式需要使用如下形式

template class, class...> class c, class... args>

void var_func(const c&v)

//「偏特化」使用者自定義非容器型別的函式

template typename cont>

void func(const type &v, std::enable_if_t::value> * =nullptr){}

//預設的復合型別模板函式

template typename cont>

void func(const cont&v, std::enable_if_t::value

&& !std::is_same_vint>, cont>

&& !std::is_same_vint>, cont>

&& !std::is_same_vint>, cont>> * =nullptr){}

//對於函式體內的auto型別的變數(由cont和type組合成的復合型別),可以通過以下手段判斷其型別

using t = std::decay_t;

if constexpr (std::is_same_v, t>)

func

(variable);

else

if constexpr (std::is_same_v)

func

(variable);

....

結論:最後採用了這種方案,結合了std::enable_if_t, std::is_same_v, std::is_base_of 等語法來實現模板函式的條件來實現了函式模板的「偏特化」

tips:

函式模板的定義和宣告必須都放到標頭檔案中,因為編譯器在編譯階段需要依據標頭檔案中模板函式的定義來實現模板的例項化

不建議將函式模板編譯成靜(動)態庫,然後原始檔只包含模板函式宣告的標頭檔案,這樣在鏈結的時候提示undefined 的類似錯誤,因為函式庫只能匯出例項化的函式,對於沒有例項化模板函式,就會出現undefined的錯誤(除非在函式庫中,將所有可能的例項化型別都例項化一遍)。建議,對模板的使用通過標頭檔案的方式。

類模板如果有預設模板引數,那麼只能在宣告或者定義其中任何乙個位置設定預設模板引數,不能兩個位置都設定。

C 類模板 函式模板全特化 偏特化的使用

一 類模板全特化 偏特化 pragma once include程式設計客棧 include template class tc void funtest template class tc void funtest template void tc funtest main.cpp include...

測試方案模板 C 函式模板的偏特化

c 標準並不支援函式模板偏特化,然而在實際開發中,我們確實需要對一些函式模板進行偏特化。本文將介紹幾種函式模板偏特化的通用方案。偏特化是相對於全特化而言的,即只特化了部分模板引數,如下 類模板偏特化demo template class myvector template class myvecto...

C 多引數模板偏特化

多引數模板必須對所有引數才能偏特化,本文給出一種解決特化單個引數的方案 例 使用loki中的多執行緒模板 singlethreaded單執行緒無需鎖 objectlevellockable多執行緒鎖單一例項 classlevellockable多執行緒鎖類 現我希望使用編譯時定義的const ifd...