一文詳解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)鍵字一樣,用于進行編譯時類型推導,不過它與auto是有一些區(qū)別的。decltype的類型推導并不是像auto一樣是從變量聲明的初始化表達式獲得變量的類型,而是總是以一個普通表達式作為參數(shù),返回該表達式的類型,而且decltype并不會對表達式進行求值。
decltype關(guān)鍵字用于查詢表達式的類型,并不會對表達式進行求值。decltype的作用是獲得一個變量或表達式的類型。decltype 不會執(zhí)行表達式而auto會,decltype僅僅推論一下表達式的類型。
對于decltype( e )而言,其判別結(jié)果受以下條件的影響:
(1)、如果e是一個標識符或者類成員的訪問表達式,則decltype(e)就是e所代表的實體的類型。如果沒有這種類型或者e是一個重載函數(shù)集,那么程序是錯誤的;
(2)、如果e是一個函數(shù)調(diào)用或者一個重載操作符調(diào)用(忽略e外面的括號),那么decltype(e)就是該函數(shù)的返回類型;
(3)、如果e不屬于以上所述的情況,則假設(shè)e的類型是 T:當e是一個左值時,decltype(e)就是T&;否則(e是一個右值),decltype(e)是T。
auto是為所有人準備的,而decltype是提供給模板開發(fā)者的。
在C++中,decltype作為操作符,用于查詢表達式的數(shù)據(jù)類型。decltype在C++11標準制定時引入,主要是為泛型編程而設(shè)計,以解決泛型編程中,由于有些類型由模板參數(shù)決定,而難以表示的問題。
下面是從其他文章中copy的測試代碼,詳細內(nèi)容介紹可以參考對應(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++淺析序列數(shù)據(jù)封裝與優(yōu)化實現(xiàn)方法
封裝是面向?qū)ο缶幊讨械陌褦?shù)據(jù)和操作數(shù)據(jù)的函數(shù)綁定在一起的一個概念,這樣能避免受到外界的干擾和誤用,從而確保了安全,數(shù)據(jù)封裝是一種把數(shù)據(jù)和操作數(shù)據(jù)的函數(shù)捆綁在一起的機制,數(shù)據(jù)抽象是一種僅向用戶暴露接口而把具體的實現(xiàn)細節(jié)隱藏起來的機制2022-12-12c++將vector迭代器轉(zhuǎn)換為指針的實現(xiàn)方式
這篇文章主要介紹了c++將vector迭代器轉(zhuǎn)換為指針的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11C/C++實現(xiàn)string和int相互轉(zhuǎn)換的常用方法總結(jié)
在C++編程中,經(jīng)常需要在字符串(string)和整型(int)之間進行轉(zhuǎn)換,本文將詳細介紹幾種在C和C++中實現(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)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下。2017-10-10