日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

C++函數模板:掌握返回類型推導的藝術

來源: 責編: 時間:2024-01-18 09:41:15 240觀看
導讀編譯器推導返回類型討論 add() 函數模板的示例,讓編譯器推導返回值的類型確實是個好主意。然而,返回類型依賴于模板類型參數,那該如何實現呢?例如,考慮以下函數模板:template <typename T1, typename T2>RetType add(const

編譯器推導返回類型

討論 add() 函數模板的示例,讓編譯器推導返回值的類型確實是個好主意。然而,返回類型依賴于模板類型參數,那該如何實現呢?例如,考慮以下函數模板:9L228資訊網——每日最新資訊28at.com

template <typename T1, typename T2>RetType add(const T1& t1, const T2& t2) {    return t1 + t2;}

在這個示例中,RetType 應該是表達式 t1 + t2 的類型,但你無法知道這一點,因為你不知道 T1 和 T2 是什么。9L228資訊網——每日最新資訊28at.com

9L228資訊網——每日最新資訊28at.com

自動類型推導

自 C++14 起,你可以讓編譯器自動推導函數的返回類型。因此,你可以簡單地將 add() 寫成如下:9L228資訊網——每日最新資訊28at.com

template <typename T1, typename T2>auto add(const T1& t1, const T2& t2) {    return t1 + t2;}

在 C++ 中,當使用 auto 關鍵字來推導函數返回值的類型時,它會自動去除表達式中的引用(reference)和 const 限定符。這意味著,如果函數的返回類型原本是一個引用或 const 類型,使用 auto 推導后,返回值將會失去這些屬性。例如,如果原本返回的是一個 const 引用,使用 auto 推導后,返回值將僅是一個值,而非引用,并且也不再是 const 類型。9L228資訊網——每日最新資訊28at.com

對于某些函數來說,這種去除引用和 const 的行為是可以接受的。例如,在 add() 函數模板中,如果使用 auto,這通常沒問題,因為 operator+(加法運算符)一般返回一個新的對象,而不是引用或 const 對象。9L228資訊網——每日最新資訊28at.com

然而,在其他一些情況下,可能需要保留函數返回值的原始屬性,比如其為引用或 const 類型。在這些情況下,簡單地使用 auto 來推導返回類型可能就不夠理想了。因此,需要使用其他方法(使用 decltype(auto) 的函數模板)來確保函數返回值的原始屬性被正確保留。9L228資訊網——每日最新資訊28at.com

auto 與 decltype 的區別

考慮以下非模板示例,了解 auto 和 decltype 之間的差異:9L228資訊網——每日最新資訊28at.com

const std::string message { "Test" };const std::string& getString() { return message; }auto s1 { getString() }; // s1 是 string 類型,進行了拷貝const auto& s2 { getString() }; // s2 是對常量的引用decltype(getString()) s3 { getString() }; // s3 是 const string& 類型decltype(auto) s4 { getString() }; // s4 也是 const string& 類型

使用 decltype(auto) 的函數模板

有了這些知識,我們可以使用 decltype(auto) 來編寫我們的 add() 函數模板,以避免去除任何 const 和引用限定符:9L228資訊網——每日最新資訊28at.com

template <typename T1, typename T2>decltype(auto) add(const T1& t1, const T2& t2) {    return t1 + t2;}

C++14 之前的方法

在 C++14 之前,也就是在函數返回類型推導和 decltype(auto) 得到支持之前,問題是通過使用 decltype(expression) 來解決的,這是 C++11 引入的。例如,你可能會寫出以下代碼:9L228資訊網——每日最新資訊28at.com

template <typename T1, typename T2>decltype(t1 + t2) add(const T1& t1, const T2& t2) {    return t1 + t2;}

然而,這是錯誤的。你在原型行的開頭使用了 t1 和 t2,但這些參數還未知。t1 和 t2 在到達參數列表末尾時才變得已知。9L228資訊網——每日最新資訊28at.com

這個問題曾經通過替代函數語法解決。注意,在這種語法中,auto 用于原型行的開頭,而實際的返回類型在參數列表之后指定(尾隨返回類型);因此,參數的9L228資訊網——每日最新資訊28at.com

名稱(以及它們的類型,從而 t1 + t2 的類型)是已知的:9L228資訊網——每日最新資訊28at.com

template<typename T1, typename T2>auto add(const T1& t1, const T2& t2) -> decltype(t1 + t2) {    return t1 + t2;}

注意:現在 C++ 支持 auto 返回類型推導和 decltype(auto),建議使用這些機制,而不是替代函數語法。9L228資訊網——每日最新資訊28at.com

9L228資訊網——每日最新資訊28at.com

C++20 的新特性

C++20 引入了一種簡化的函數模板語法。再次回顧前面的 add() 函數模板。這里是推薦的版本:9L228資訊網——每日最新資訊28at.com

template <typename T1, typename T2>decltype(auto) add(const T1& t1, const T2& t2) {    return t1 + t2;}

看這個示例,為了指定一個簡單的函數模板,語法顯得相當冗長。使用簡化的函數模板語法,可以更優雅地寫成如下:9L228資訊網——每日最新資訊28at.com

decltype(auto) add(const auto& t1, const auto& t2) {    return t1 + t2;}

使用這種語法,不再需要 template<> 規范來指定模板參數。相反,以前在實現中使用的 T1 和 T2 類型現在被指定為 auto。這種簡化的語法只是語法糖;編譯器會自動將這種簡化實現轉換為更長的原始代碼。基本上,每個被指定為 auto 的函數參數都成為一個模板類型參數。9L228資訊網——每日最新資訊28at.com

需要注意的兩個問題

(1) 不同的模板類型參數:每個被指定為auto的參數都成為不同的模板類型參數。假設你有這樣一個函數模板:9L228資訊網——每日最新資訊28at.com

template <typename T>decltype(auto) add(const T& t1, const T& t2) {    return t1 + t2;}

這個版本只有一個模板類型參數,而函數的兩個參數 t1 和 t2 都是 const T& 類型。對于這樣的函數模板,你不能使用簡化語法,因為這將被轉換為具有兩個不同模板類型參數的函數模板。9L228資訊網——每日最新資訊28at.com

(2) 無法顯式使用推導類型:你不能在函數模板的實現中顯式使用這些自動推導的類型,因為這些自動推導的類型沒有名稱。如果你需要這樣做,你要么需要繼續使用普通的函數模板語法,要么使用 decltype() 來確定類型。9L228資訊網——每日最新資訊28at.com

// C++50 中的 auto 使用auto auto(auto... args) {    return (... + args);}

本文鏈接:http://www.www897cc.com/showinfo-26-64104-0.htmlC++函數模板:掌握返回類型推導的藝術

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 2024年不容錯過的十個開發框架

下一篇: 微服務和無服務器架構時代的持續測試

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 唐山市| 门源| 漯河市| 阳城县| 常州市| 平阴县| 鄱阳县| 温泉县| 叙永县| 潍坊市| 开封市| 贵溪市| 双城市| 安丘市| 海丰县| 武功县| 齐齐哈尔市| 通化市| 汝南县| 天柱县| 黄大仙区| 北票市| 定陶县| 治县。| 宁强县| 云南省| 湖北省| 东乡| 瑞丽市| 修文县| 凤冈县| 微山县| 肇源县| 城口县| 怀集县| 临朐县| 云浮市| 南江县| 诸暨市| 营山县| 平阳县|