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关键字一样,用于进行编译时类型推导,不过它与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;
GitHub:https://github.com/fengbingchun/Messy_Test
C++11中decltype的使用的更多相关文章
- c++11 之 decltype
在C++中,decltype作为操作符,用于查询表达式的数据类型.decltype在C++11标准制定时引入,主要是为泛型编程而设计,以解决泛型编程中,由于有些类型由模板参数决定,而难以(甚至不可能) ...
- C++11 中值得关注的几大变化(网摘)
C++11 中值得关注的几大变化(详解) 原文出处:[陈皓 coolshell] 源文章来自前C++标准委员会的 Danny Kalev 的 The Biggest Changes in C++11 ...
- C++11 中值得关注的几大变化(详解)
源文章来自前C++标准委员会的 Danny Kalev 的 The Biggest Changes in C++11 (and Why You Should Care),赖勇浩做了一个中文翻译在这里. ...
- c++11——auto,decltype类型推导
c++11中引入了auto和decltype关键字实现类型推导,通过这两个关键字不仅能够方便的获取复杂的类型,而且还能简化书写,提高编码效率. auto和decltype的类型推导都是编译器在 ...
- c++11 中的注意事项
1. C++11标准中让类的析构函数默认也是noexcept(true)的. 但如果显式地为析构函数指定了noexcept,或者类的基类或成员有noexcept(false)的析构函数,析构函数就不会 ...
- C++11的decltype关键字
C++11的decltype关键字 概述 decltype关键字和auto有异曲同工之处 有时我们希望从表达式的类型推断出要定义的变量类型,但是不想用该表达式的值初始化变量(如果要初始化就用auto了 ...
- 从linux0.11中起动部分代码看汇编调用c语言函数
上一篇分析了c语言的函数调用栈情况,知道了c语言的函数调用机制后,我们来看一下,linux0.11中起动部分的代码是如何从汇编跳入c语言函数的.在LINUX 0.11中的head.s文件中会看到如下一 ...
- C++ 11 中的右值引用
C++ 11 中的右值引用 右值引用的功能 首先,我并不介绍什么是右值引用,而是以一个例子里来介绍一下右值引用的功能: #include <iostream> #include &l ...
- IOS中的Block与C++11中的lambda
ios中的block 可以说是一种函数指针,但更确切的讲,其实际上其应该算是object-c对C++11中lambda的支持或者说是一个语言上的变体,其实际内容是一样的,C++的lambda我已经有简 ...
随机推荐
- 20150103 海南铁汉vs哈尔滨毅腾
本文首发于『懂球帝』 这一场球赛虽然极其普通,在各位懂球帝面前或许不值得一提,但它极具历史意义,因为这是海南第一个职业联赛队伍的首场正式比赛,同时也是海南铁汉队第一次在正式比赛中与球迷们见面. 稍做一 ...
- Java Android 32位16位 MD5加密
// md5加密 32位小写 private String Md5(String sourceStr) { String result = ""; try { MessageDig ...
- linux shell中 if else以及大于、小于、等于逻辑表达式介绍
在linux shell编程中,大多数情况下,可以使用测试命令来对条件进行测试,这里简单的介绍下, 比如比较字符串.判断文件是否存在及是否可读等,通常用"[]"来表示条件测试. 注 ...
- windows网络模型之完成端口(CompletionPort)详解 (转)
转载自:https://blog.csdn.net/piggyxp/article/details/6922277 目录: 1. 完成端口的优点 2. 完成端口程序的运行演示 3. 完成端口的相关概念 ...
- BZOJ4415:[SHOI2013]发牌(线段树)
Description 假设一开始,荷官拿出了一副新牌,这副牌有N张不同的牌,编号依次为1到N.由于是新牌,所以牌是按照顺序排好的,从牌库顶开始,依次为1, 2,……直到N,N号牌在牌库底.为了发完所 ...
- mxnet数据操作
# coding: utf-8 # In[2]: from mxnet import nd # In[3]: x = nd.arange(12) x # In[4]: x.shape,x.size # ...
- Codeforces 336C 0-1背包
题意:每个水果有两个值,一个美味度 a,一个卡路里 b,从中挑选一些,要求 sum(aj) / sum(bj) = k,使得 sum(a) 最大. 分析:没有那个条件就是一个01背包,可以转换,对公式 ...
- UVA11294 Wedding
嘟嘟嘟 大佬们都说这是2-SAT入门题,然而对于刚学2_SAT的本菜鸡来说半天才理解…… 题面:新娘和新郎不能坐在同一侧,妻子和丈夫不能坐在同一侧,有**关系的两个人必须至少一个坐在新娘一侧,问方案. ...
- js 实现div跟随鼠标移动
今天看到了一个自己可以随心所欲的拖到div到页面的任意位置.感觉挺好的,就心血来潮的查询了一下,看看网友做的 代码如下: <script>function doit(){ var obj ...
- onInterceptTouchEvent和onTouchEvent调用关系详解 ...
http://blog.csdn.net/lvxiangan/article/details/9309927 老实说,这两个小东东实在是太麻烦了,很不好懂,我自己那api文档都头晕,在网上找到很多资料 ...