C++精要分析decltype的作用及用法
獲取表達式的類型
在編寫程序的過程中,我們可能會有一種需求,就是希望可以根據(jù)一個變量的類型,來定義具有相同類型的變量。例如定義int x = 0;
,那么我們是否可以不使用int
關鍵字,僅使用x就定義一個新的整型變量y呢?
答案是可以的,C++11新增的decltype
關鍵字就是干這個用的。上述需求用代碼實現(xiàn)如下:
int x = 0; decltype(x) y = 2; // y的類型為int
decltype
是在編譯期用來推導表達式類型的。其語法格式為:decltype(expression)
。大家可以看到,decltype
是可以對一個表達式取類型的,并不僅是單個的變量。所以,把形式再擴展一下:
int x = 0; decltype(x) y = 2; decltype(x + y) z = 3; // z的類型為int
到這一步,相信大家已經(jīng)可以基本掌握其特性,在工作中能運用了。當然,僅知道這些還是不夠的,作為C++程序員怎么能停下探索的腳步呢。
推導規(guī)則
decltype
的推導規(guī)則,是面試中最容易挖坑的地方。你要是不信,那就先回答下面這些問題吧:
const int func_one(); decltype(func_one()) a1 = 0; // a1是什么類型? struct TestData { int x;}; cosnt TestData b_node = TestData(); decltype(b_node.x) b1 = 0; // b1是什么類型? decltype((b_node.x)) b2 = b1; // b2是什么類型? int n = 0, m = 0; decltype(n + m) c1 = 0; // c1是什么類型? decltype(n += m) c2 = c1; // c2是什么類型?
注釋中有五個問題,如果你全都答對而且不是蒙的,那請開班授課吧,我會第一個報名。先公布一下答案,看看自己答對了多少吧。
a1: int
b1: int
b2: const int &
c1: int
c2: int &
如果這個答案讓你覺得有些暈頭轉向,不要緊,先來看下規(guī)則描述吧:
- 如果expression表達式是標識符、類訪問表達式,
decltype(exp)
和exp的類型一致; - 如果expression是函數(shù)調用,則
decltype(exp)
和返回值的類型一致; - 其他情況,如果expression是一個左值,則
decltype(exp)
是exp類型的左值引用,否則和exp類型一致。
現(xiàn)在,將規(guī)則理解之后,再看一遍代碼和答案,是否找到規(guī)律了呢?相信在面試中遇到這樣的問題,你已經(jīng)可以應對自如了。
返回類型后置
在說明decltype
的一個高級用法之前,我們先了解C++11的一個新特性,就是函數(shù)返回類型后置。與之相對的,就是返回類型前置,這是我們最熟悉的函數(shù)聲明格式。例如:int foo();
而返回類型后置的示例如下:
auto foo() -> int { return 0; }
在上面的代碼中,auto關鍵字是一個占位符,int是其實際返回類型。初看起來,后置聲明與前置聲明在功能上是一樣的,那它難道是一個多余的設計嗎?它當然自有用武之地。
在需要返回比較復雜的類型時,使用后置式聲明可以簡化代碼并使其可讀性更好。例如要返回的類型是函數(shù)指針,前置式聲明就必須先用typedef
進行預定義,否則語法不允許。而后置式聲明則可以直接實現(xiàn),無需預定義,如下代碼所示。
int exam(bool b) { int ret = -1; if (b) { ret = 0; } else if (!b) { ret = 1; } return ret; } auto foo() -> int(*)(bool) { return exam; } int main() { auto fn = foo(); cout << fn(true) << endl; cout << fn(false) << endl; }
高級用法
現(xiàn)在正式介紹decltype
與函數(shù)返回類型后置相結合,在模板編程中的用法,就是用于推導函數(shù)模板的返回類型。之所以將此歸為高級用法,也是因為模板在C++中雖然功能強大,但屬實復雜不易理解。一般是編寫基礎功能庫或是算法庫時,使用到模板的特性。
先看一段示例代碼:
template<class T1, class T2> auto sum(T1 t1, T2 t2) -> decltype(t1 + t2) { return t1 + t2; } int main() { auto ret = sum(4.6, 123); cout << ret << endl; }
其精髓之處,就在于可以靈活支持T1與T2不同類型的組合,而不必為每種返回類型都去寫一個實現(xiàn)。例如int+int, double+int, string+string
等各種組合情況。
但如果是把decltype(t1 + t2)
以前置寫法替換auto,則會產生編譯錯誤。道理很簡單,編譯器對t1+t2
的參數(shù)類型還一無所知,只有在解析到返回值時,才能最終確定函數(shù)的返回類型,這就是decltype
加上函數(shù)返回類型后置在模板編程中的妙用。
到此這篇關于C++精要分析decltype的作用及用法的文章就介紹到這了,更多相關C++ decltype內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C++ 將一個文件讀入數(shù)組再讀出數(shù)組的方法
今天小編就為大家分享一篇C++ 將一個文件讀入數(shù)組再讀出數(shù)組的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07C++深入分析數(shù)據(jù)在內存中的存儲形態(tài)
使用編程語言進行編程時,需要用到各種變量來存儲各種信息。變量保留的是它所存儲的值的內存位置。這意味著,當您創(chuàng)建一個變量時,就會在內存中保留一些空間。您可能需要存儲各種數(shù)據(jù)類型的信息,操作系統(tǒng)會根據(jù)變量的數(shù)據(jù)類型,來分配內存和決定在保留內存中存儲什么2023-01-01Android App仿微信界面切換時Tab圖標變色效果的制作方法
這篇文章主要介紹了Android App仿微信界面切換時Tab圖標變色效果的制作方法,重點講解了圖標的繪制技巧,需要的朋友可以參考下2016-04-04