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关键字一样,用于进行编译时类型推导,不过它与auto是有一些区别的。decltype的类型推导并不是像auto一样是从变量声明的初始化表达式获得变量的类型,而是总是以一个普通表达式作为参数,返回该表达式的类型,而且decltype并不会对表达式进行求值。

decltype关键字用于查询表达式的类型,并不会对表达式进行求值。decltype的作用是获得一个变量或表达式的类型。decltype 不会执行表达式而auto会,decltype仅仅推论一下表达式的类型。

对于decltype( e )而言,其判别结果受以下条件的影响:

(1)、如果e是一个标识符或者类成员的访问表达式,则decltype(e)就是e所代表的实体的类型。如果没有这种类型或者e是一个重载函数集,那么程序是错误的;

(2)、如果e是一个函数调用或者一个重载操作符调用(忽略e外面的括号),那么decltype(e)就是该函数的返回类型;

(3)、如果e不属于以上所述的情况,则假设e的类型是 T:当e是一个左值时,decltype(e)就是T&;否则(e是一个右值),decltype(e)是T。

auto是为所有人准备的,而decltype是提供给模板开发者的。

在C++中,decltype作为操作符,用于查询表达式的数据类型。decltype在C++11标准制定时引入,主要是为泛型编程而设计,以解决泛型编程中,由于有些类型由模板参数决定,而难以表示的问题。

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的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;

GitHubhttps://github.com/fengbingchun/Messy_Test

C++11中decltype的使用的更多相关文章

  1. c++11 之 decltype

    在C++中,decltype作为操作符,用于查询表达式的数据类型.decltype在C++11标准制定时引入,主要是为泛型编程而设计,以解决泛型编程中,由于有些类型由模板参数决定,而难以(甚至不可能) ...

  2. C++11 中值得关注的几大变化(网摘)

    C++11 中值得关注的几大变化(详解) 原文出处:[陈皓 coolshell] 源文章来自前C++标准委员会的 Danny Kalev 的 The Biggest Changes in C++11 ...

  3. C++11 中值得关注的几大变化(详解)

    源文章来自前C++标准委员会的 Danny Kalev 的 The Biggest Changes in C++11 (and Why You Should Care),赖勇浩做了一个中文翻译在这里. ...

  4. c++11——auto,decltype类型推导

    c++11中引入了auto和decltype关键字实现类型推导,通过这两个关键字不仅能够方便的获取复杂的类型,而且还能简化书写,提高编码效率.     auto和decltype的类型推导都是编译器在 ...

  5. c++11 中的注意事项

    1. C++11标准中让类的析构函数默认也是noexcept(true)的. 但如果显式地为析构函数指定了noexcept,或者类的基类或成员有noexcept(false)的析构函数,析构函数就不会 ...

  6. C++11的decltype关键字

    C++11的decltype关键字 概述 decltype关键字和auto有异曲同工之处 有时我们希望从表达式的类型推断出要定义的变量类型,但是不想用该表达式的值初始化变量(如果要初始化就用auto了 ...

  7. 从linux0.11中起动部分代码看汇编调用c语言函数

    上一篇分析了c语言的函数调用栈情况,知道了c语言的函数调用机制后,我们来看一下,linux0.11中起动部分的代码是如何从汇编跳入c语言函数的.在LINUX 0.11中的head.s文件中会看到如下一 ...

  8. C++ 11 中的右值引用

    C++ 11 中的右值引用 右值引用的功能 首先,我并不介绍什么是右值引用,而是以一个例子里来介绍一下右值引用的功能: #include <iostream>    #include &l ...

  9. IOS中的Block与C++11中的lambda

    ios中的block 可以说是一种函数指针,但更确切的讲,其实际上其应该算是object-c对C++11中lambda的支持或者说是一个语言上的变体,其实际内容是一样的,C++的lambda我已经有简 ...

随机推荐

  1. libevent-select模型分析

    下面内容为windows下select模型分析,原博客链接 http://blog.csdn.net/fish_55_66/article/details/50352080 https://www.c ...

  2. python:线程进阶

    1,守护线程 import time from threading import Thread def func(): print('开始执行子线程') time.sleep(3) print('子线 ...

  3. VMWARE下CentOS7虚拟机网络配置

    注:本文仅针对新装的虚拟机,#ip addr 获取不到ip信息,无法连接网络的情况提供一种参考解决方案. 1.左上角点击“编辑”->“虚拟网络编辑器”.新建一个NAT模式的网络. 2.配置虚拟机 ...

  4. Windows 备用数据流(ADS)的妙用___转载

    NTFS交换数据流(Alternate Data Streams,简称ADS)是NTFS磁盘格式的一个特性,在NTFS文件系统下,每个文件都可以存在多个数据流.通俗的理解,就是其它文件可以“寄宿”在某 ...

  5. js正则判断日期

    //****************************************************************************// Function ID : Commo ...

  6. 【洛谷P1039】侦探推理

    侦探推理 题目链接 这是一道恶心至极的模拟题 我们可以枚举罪犯是谁,今天是星期几,从而判断每个人说的话是真是假 若每个人说的话的真假一致,且说谎话的人数<=k且说真话的人数<=m-k,就是 ...

  7. 【洛谷P2216】[HAOI2007]理想的正方形

    理想的正方形 [题目描述] 一个a*b的矩阵,从中取一个n*n的子矩阵,使所选矩阵中的最大数与最小数的差最小. 思路: 二维的滑动窗口 对于每行:用一个单调队列维护,算出每个长度为n的区间的最大值和最 ...

  8. Angularjs实例4

    <!DOCTYPE html><html lang="zh-cn" ng-app=""><head><meta htt ...

  9. Java面向对象知道这些就够了

    面向对象 面向对象是一种思维方式,相对于面向过程而言的. 面向过程在流程中关注动作执行的每一个细节 — 自己动手做 面向对象重点找这个对象,只要找到了对象,那么这个对象所具有的功能就能够被使用 — 找 ...

  10. Question 20171115 String&&StringBuffer&&StringBuilder的区别与联系?

    Question 20171114 String&&StringBuffer&&StringBuilder的区别和联系 创建成功的String对象,其长度是固定的,内容 ...