一文詳解C++11中decltype的使用
The decltype type specifier yields the type of a specified expression. The decltype type specifier, together with the auto keyword, is useful primarily to developers who write template libraries. Use auto and decltype to declare a template function whose return type depends on the types of its template arguments. Or,use auto and decltype to declare a template function that wraps a call to another function, and then returns the return type of the wrapped function.
The compiler uses the following rules to determine the type of the expression parameter:
(1)、If the expression parameter is an identifier or a class member access, decltype(expression) is the type of the entity named by expression. If there is no such entity or the expression parameter names a set of overloaded functions,the compiler yields an error message.
(2)、If the expression parameter is a call to a function or an overloaded operator function, decltype(expression) is the return type of the function. Parentheses around an overloaded operator are ignored.
(3)、If the expression parameter is an rvalue, decltype(expression) is the type of expression. If the expression parameter is an lvalue, decltype(expression) is an lvalue reference to the type of expression.
decltype is useful when declaring types that are difficult or impossible to declare using standard notation, like lambda-related types or types that depend on template parameters.
decltype is a standard C++11 feature. It is an "operator" which takes an expression and returns a type.
decltype與auto關(guān)鍵字一樣,用于進(jìn)行編譯時(shí)類型推導(dǎo),不過它與auto是有一些區(qū)別的。decltype的類型推導(dǎo)并不是像auto一樣是從變量聲明的初始化表達(dá)式獲得變量的類型,而是總是以一個(gè)普通表達(dá)式作為參數(shù),返回該表達(dá)式的類型,而且decltype并不會(huì)對(duì)表達(dá)式進(jìn)行求值。
decltype關(guān)鍵字用于查詢表達(dá)式的類型,并不會(huì)對(duì)表達(dá)式進(jìn)行求值。decltype的作用是獲得一個(gè)變量或表達(dá)式的類型。decltype 不會(huì)執(zhí)行表達(dá)式而auto會(huì),decltype僅僅推論一下表達(dá)式的類型。
對(duì)于decltype( e )而言,其判別結(jié)果受以下條件的影響:
(1)、如果e是一個(gè)標(biāo)識(shí)符或者類成員的訪問表達(dá)式,則decltype(e)就是e所代表的實(shí)體的類型。如果沒有這種類型或者e是一個(gè)重載函數(shù)集,那么程序是錯(cuò)誤的;
(2)、如果e是一個(gè)函數(shù)調(diào)用或者一個(gè)重載操作符調(diào)用(忽略e外面的括號(hào)),那么decltype(e)就是該函數(shù)的返回類型;
(3)、如果e不屬于以上所述的情況,則假設(shè)e的類型是 T:當(dāng)e是一個(gè)左值時(shí),decltype(e)就是T&;否則(e是一個(gè)右值),decltype(e)是T。
auto是為所有人準(zhǔn)備的,而decltype是提供給模板開發(fā)者的。
在C++中,decltype作為操作符,用于查詢表達(dá)式的數(shù)據(jù)類型。decltype在C++11標(biāo)準(zhǔn)制定時(shí)引入,主要是為泛型編程而設(shè)計(jì),以解決泛型編程中,由于有些類型由模板參數(shù)決定,而難以表示的問題。
下面是從其他文章中copy的測(cè)試代碼,詳細(xì)內(nèi)容介紹可以參考對(duì)應(yīng)的reference:
#include "decltype.hpp" #include <iostream> #include <string> #include <utility> #include <iomanip> // // reference: http://en.cppreference.com/w/cpp/language/decltype struct A { double x; }; const A* a = new A{ 0 }; 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 int test_decltype1() { int i = 33; decltype(i) j = i * 2; std::cout << "i = " << i << ", " << "j = " << j << '\n'; auto f = [](int a, int b) -> int { return a * b; }; decltype(f) g = f; // the type of a lambda function is unique and unnamed i = f(2, 2); j = g(3, 3); std::cout << "i = " << i << ", " << "j = " << j << '\n'; return 0; } /// // reference: https://msdn.microsoft.com/zh-cn/library/dd537655.aspx template<typename T1, typename T2> auto Plus(T1&& t1, T2&& t2) -> decltype(std::forward<T1>(t1) +std::forward<T2>(t2)) { return std::forward<T1>(t1) +std::forward<T2>(t2); } class X { friend X operator+(const X& x1, const X& x2) { return X(x1.m_data + x2.m_data); } public: X(int data) : m_data(data) {} int Dump() const { return m_data; } private: int m_data; }; int test_decltype2() { // Integer int i = 4; std::cout << "Plus(i, 9) = " << Plus(i, 9) << std::endl; // Floating point float dx = 4.0; float dy = 9.5; std::cout << std::setprecision(3) << "Plus(dx, dy) = " << Plus(dx, dy) << std::endl; // String std::string hello = "Hello, "; std::string world = "world!"; std::cout << Plus(hello, world) << std::endl; // Custom type X x1(20); X x2(22); X x3 = Plus(x1, x2); std::cout << "x3.Dump() = " << x3.Dump() << std::endl; return 0; } /// // reference: http://thbecker.net/articles/auto_and_decltype/section_06.html struct S { S(){ m_x = 42; } int m_x; }; int x; const int cx = 42; const int& crx = x; const S* p = new S(); // x is declared as an int: x_type is int. typedef decltype(x) x_type; // auto also deduces the type as int: a_ is an int. auto a_ = x; // cx is declared as const int: cx_type is const int. typedef decltype(cx) cx_type; // auto drops the const qualifier: b is int. auto b = cx; // crx is declared as const int&: crx_type is const int&. typedef decltype(crx) crx_type; // auto drops the reference and the const qualifier: c is an int. auto c = crx; // S::m_x is declared as int: m_x_type is int // Note that p->m_x cannot be assigned to. It is effectively // constant because p is a pointer to const. But decltype goes // by the declared type, which is int. typedef decltype(p->m_x) m_x_type; // auto sees that p->m_x is const, but it drops the const // qualifier. Therefore, d is an int. auto d = p->m_x;
GitHub: https://github.com/fengbingchun/Messy_Test
到此這篇關(guān)于一文詳解C++11中decltype的使用的文章就介紹到這了,更多相關(guān)C++11 decltype內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++淺析序列數(shù)據(jù)封裝與優(yōu)化實(shí)現(xiàn)方法
封裝是面向?qū)ο缶幊讨械陌褦?shù)據(jù)和操作數(shù)據(jù)的函數(shù)綁定在一起的一個(gè)概念,這樣能避免受到外界的干擾和誤用,從而確保了安全,數(shù)據(jù)封裝是一種把數(shù)據(jù)和操作數(shù)據(jù)的函數(shù)捆綁在一起的機(jī)制,數(shù)據(jù)抽象是一種僅向用戶暴露接口而把具體的實(shí)現(xiàn)細(xì)節(jié)隱藏起來的機(jī)制2022-12-12C++簡(jiǎn)明講解缺省參數(shù)與函數(shù)重載的用法
所謂缺省參數(shù),顧名思義,就是在聲明函數(shù)的某個(gè)參數(shù)的時(shí)候?yàn)橹付ㄒ粋€(gè)默認(rèn)值,在調(diào)用該函數(shù)的時(shí)候如果采用該默認(rèn)值,你就無須指定該參數(shù)。C++ 允許多個(gè)函數(shù)擁有相同的名字,只要它們的參數(shù)列表不同就可以,這就是函數(shù)的重載,借助重載,一個(gè)函數(shù)名可以有多種用途2022-06-06c++將vector迭代器轉(zhuǎn)換為指針的實(shí)現(xiàn)方式
這篇文章主要介紹了c++將vector迭代器轉(zhuǎn)換為指針的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11C/C++實(shí)現(xiàn)string和int相互轉(zhuǎn)換的常用方法總結(jié)
在C++編程中,經(jīng)常需要在字符串(string)和整型(int)之間進(jìn)行轉(zhuǎn)換,本文將詳細(xì)介紹幾種在C和C++中實(shí)現(xiàn)這兩種類型轉(zhuǎn)換的常用方法,有需要的可以參考下2024-01-01關(guān)于C++11的統(tǒng)一初始化語法示例詳解
C++之前的初始化語法很亂,有四種初始化方式,而且每種之前甚至不能相互轉(zhuǎn)換,但從C++11出現(xiàn)后就好了,所以這篇文章主要給大家介紹了關(guān)于C++11的統(tǒng)一初始化語法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。2017-10-10