decltype
說明符 (C++11 起)
來自 cppreference.com
檢查實體或表示式的宣告型別和值類別。
目錄 |
[編輯] 語法
decltype ( 實體 ) |
(1) | ||||||||
decltype ( 表示式 ) |
(2) | ||||||||
[編輯] 解釋
1) 如果引數是未加括號的id-表示式或未加括號的類成員訪問表示式,則 decltype 產生該表示式所命名的實體的型別。如果沒有這樣的實體,或者如果引數命名了一組過載函式,則程式格式不正確。
(C++17 起) | |
如果引數是命名非型別模板引數的未加括號的id-表示式,則 decltype 產生模板引數的型別(在模板引數聲明瞭佔位符型別的情況下,執行任何必要的型別推導之後)。即使實體是模板引數物件(一個 const 物件),該型別也是非 const 的。 |
(C++20 起) |
2) 如果引數是型別為
T
的任何其他表示式,並且c) 如果表示式的值類別是prvalue,則 decltype 產生 T。
由於不建立臨時物件,因此型別無需完整或具有可用的解構函式,並且可以是抽象的。此規則不適用於子表示式:在 decltype(f(g())) 中,g() 必須具有完整型別,但 f() 則不必。
如果表示式是返回類型別純右值的函式呼叫,或是其右運算元是此類函式呼叫的逗號表示式,則不為該純右值引入臨時物件。 |
(C++17 前) |
如果表示式是純右值(除了 (可能加括號的) 即時呼叫)(C++20 起),則不會從該純右值具體化臨時物件:這樣的純右值沒有結果物件。 |
(C++17 起) |
請注意,如果物件的名稱被括號括起來,它將被視為普通的左值表示式,因此 decltype(x) 和 decltype((x)) 通常是不同的型別。
decltype
在宣告難以或不可能使用標準符號宣告的型別時非常有用,例如與 lambda 相關的型別或依賴於模板引數的型別。
[編輯] 注意
功能測試宏 | 值 | 標準 | 特性 |
---|---|---|---|
__cpp_decltype |
200707L |
(C++11) | decltype |
[編輯] 關鍵詞
[編輯] 示例
執行此程式碼
#include <cassert> #include <iostream> #include <type_traits> struct A { double x; }; const A* a; decltype(a->x) y; // type of y is double (declared type) decltype((a->x)) z = y; // type of z is const double& (lvalue expression) template<typename T, typename U> auto add(T t, U u) -> decltype(t + u) // return type depends on template parameters // return type can be deduced since C++14 { return t + u; } const int& getRef(const int* p) { return *p; } static_assert(std::is_same_v<decltype(getRef), const int&(const int*)>); auto getRefFwdBad(const int* p) { return getRef(p); } static_assert(std::is_same_v<decltype(getRefFwdBad), int(const int*)>, "Just returning auto isn't perfect forwarding."); decltype(auto) getRefFwdGood(const int* p) { return getRef(p); } static_assert(std::is_same_v<decltype(getRefFwdGood), const int&(const int*)>, "Returning decltype(auto) perfectly forwards the return type."); // Alternatively: auto getRefFwdGood1(const int* p) -> decltype(getRef(p)) { return getRef(p); } static_assert(std::is_same_v<decltype(getRefFwdGood1), const int&(const int*)>, "Returning decltype(return expression) also perfectly forwards the return type."); int main() { int i = 33; decltype(i) j = i * 2; static_assert(std::is_same_v<decltype(i), decltype(j)>); assert(i == 33 && 66 == j); auto f = [i](int av, int bv) -> int { return av * bv + i; }; auto h = [i](int av, int bv) -> int { return av * bv + i; }; static_assert(!std::is_same_v<decltype(f), decltype(h)>, "The type of a lambda function is unique and unnamed"); decltype(f) g = f; std::cout << f(3, 3) << ' ' << g(3, 3) << '\n'; }
輸出
42 42
[編輯] 參考
擴充套件內容 |
---|
|
本節不完整 原因:需要更正。參見:討論:錯誤的引用。 |
[編輯] 參見
auto 說明符 (C++11) |
指定從表示式推導的型別 |
(C++11) |
獲取模板型別引數物件的引用,用於未求值上下文 (函式模板) |
(C++11) |
檢查兩個型別是否相同 (類模板) |
C 文件 for typeof
|