[Effective Modern C++] Item 3. Understand decltype - 了解decltype
条款三 了解decltype
基础知识
提供一个变量或者表达式,decltype会返回其类型,但是返回的内容会使人感到奇怪。
以下是一些简单的推断类型:
const int i = ; // decltype(i) -> const int
bool f(const Widget& w); // decltype(w) -> const Widget&, decltype(f) -> bool(const Widget&)
struct Point {
int x, y;
} // decltype(Point::x) -> int
Widget w; // decltype(w) -> Widget
if(f(w)); // decltype(f(w)) -> bool
template<typename T>
class vector {
public:
T& operator[](std::size_t index);
};
vector<int> v; // decltype(v) -> vector<int>
if(v[] == ); // decltype(v[0]) -> int&
在C++11中,decltype的主要作用是推断根据形参类型推断返回类型。
对于std::vector<bool>,operator[]返回的并不是bool&,而是一个新的对象。
一种返回类型的推断的用法:
template<typename Container, typename Index>
auto authAndAccess(Container& c, Index i) -> decltype(C[i]){
authenticateUser();
return c[i];
}
C++11允许允许单语句lambda返回类型的推断,C+14扩展到所有lambda和函数。
// C++14版本,但是会有问题
template<typename Container, typename Index>
auto authAndAccess(Container& c, Index i){
authenticateUser();
return c[i];
}
以上函数虽然使用了auto,但套用auto的规则会出问题。如以上c[i]返回int&,但是根据推断规则会去掉引用类型,造成不能修改。
以下代码可以正确返回类型:
// C++14版本,可以正确返回类型
template<typename Container, typename Index>
decltype(auto) authAndAccess(Container& c, Index i){
authenticateUser();
return c[i];
}
auto与decltype(auto)的区别:
Widget w;
const Widget& cw = w;
auto myWidget1 = cw; // myWidget1 -> Widget
decltype(auto) myWidget2 = cw; // myWidget2 -> const Widget&
为了使得函数可以同时传入左值和右值,函数引入通用引用,正确形式如下:
// final C++14 version
template<typename Container, typename Index>
decltype(auto) authAndAccess(Container&& c, Index i){
authenticateUser();
return std::forward<Container>(c)[i];
} // final C++1 version
template<typename Container, typename Index>
auto authAndAccess(Container&& c, Index i)
-> decltype(std::forward<Container>(c)[i]){
authenticateUser();
return std::forward<Container>(c)[i];
}
在使用decltype时,变量外加上括号会改变推断类型:
int x = ;
decltype(x); // -> int
decltype((x)); // -> int&
总结
- decltype总是产生没经过修改的变量或表达式的类型
- 对于类型为T的左值表达式而非变量名,decltype总是返回T&类型
- C++14支持decltype(auto),其就像auto一样从初始化中推断类型,但是使用decltype的来推断类型
[Effective Modern C++] Item 3. Understand decltype - 了解decltype的更多相关文章
- [Effective Modern C++] Item 2. Understand auto type deduction - 了解auto类型推断
条款二 了解auto类型推断 基础知识 除了一处例外,auto的类型推断与template一样.存在一个直接的从template类型推断到auto类型推断的映射 三类情况下的推断如下所示: // ca ...
- [Effective Modern C++] Item 1. Understand template type deduction - 了解模板类型推断
条款一 了解模板类型推断 基本情况 首先定义函数模板和函数调用的形式如下,在编译期间,编译器推断T和ParamType的类型,两者基本不相同,因为ParamType常常包含const.引用等修饰符 t ...
- [Effective Modern C++] Item 7. Distinguish between () and {} when creating objects - 辨别使用()与{}创建对象的差别
条款7 辨别使用()与{}创建对象的差别 基础知识 目前已知有如下的初始化方式: ); ; }; }; // the same as above 在以“=”初始化的过程中没有调用赋值运算,如下例所示: ...
- [Effective Modern C++] Item 6. Use the explicitly typed initializer idiom when auto deduces undesired types - 当推断意外类型时使用显式的类型初始化语句
条款6 当推断意外类型时使用显式的类型初始化语句 基础知识 当使用std::vector<bool>的时候,类型推断会出现问题: std::vector<bool> featu ...
- [Effective Modern C++] Item 5. Prefer auto to explicit type declarations - 相对显式类型声明,更倾向使用auto
条款5 相对显式类型声明,更倾向使用auto 基础知识 auto能大大方便变量的定义,可以表示仅由编译器知道的类型. template<typename It> void dwim(It ...
- [Effective Modern C++] Item 4. Know how to view deduced types - 知道如何看待推断出的类型
条款四 知道如何看待推断出的类型 基础知识 有三种方式可以知道类型推断的结果: IDE编辑器 编译器诊断 运行时输出 使用typeid()以及std::type_info::name可以获取变量的类型 ...
- Effective Modern C++ Item 27:重载universal references
假设有一个接收universal references的模板函数foo,定义如下: template<typename T> void foo(T&& t) { cout ...
- Effective Modern C++ Item 37:确保std::thread在销毁时是unjoinable的
下面这段代码,如果调用func,按照C++的标准,程序会被终止(std::terminate) void func() { std::thread t([] { std::chrono::micros ...
- Effective Modern C++ 42 Specific Ways to Improve Your Use of C++11 and C++14
Item 1: Understand template type deduction. Item 2: Understand auto type deduction. Item 3: Understa ...
随机推荐
- php中mail()改用msmtp发送邮件
php中的mail()函数默认调用的是sendmail,这次我将其换成了轻量级的msmtp.在次过程中涉及到:修改配置文件php.ini,创建配置文件msmtprc或(.msmtprc)并修改其权限. ...
- C++ 查找文件夹下的文件
#include <string> #include <vector> #include <cstring> #include <cstdio> #in ...
- CDZSC_2015寒假新人(2)——数学 D
D - D Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status ...
- (原)Ubuntu16中卸载并重新安装google的Protocol Buffers
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5782992.html 目前最新的是1.6.1 1. 卸载掉老版本的Protocol: sudo apt ...
- Windows安装TensorFlow-Docker Installation of TensorFlow on Windows
TensorFlow是Google开发的进行Deep Learning的包,目前只是支持在Linux和OSX上运行.不过这个秋季或许就有支持Windows的版本出现了,那么对于使用Windows的开发 ...
- 连接oracle数据库出现:ORA-12505,TNS:listener does not currently know of SID given in connect descriptor
Java使用 jdbc:oracle:thin:@11.1.0.14:1521:orcl 连接oracle数据库出现: ORA-12505,TNS:listener does not currentl ...
- Typecho 代码阅读笔记(二) - 数据库访问
转载请注明出处:http://blog.csdn.net/jh_zzz 这一块比较复杂,我还没有完全理解为什么要把 SQL 语句的组装搞这么复杂. 从一个普通皮肤页面开始 themes/default ...
- Linux实现SSH无密码登录(对目录权限的设置非常详细,可以参考一下)
假设服务器IP地址为192.168.1.1,机器名:cluster.hpc.org 客户端IP地址为172.16.16.1,机器名:p470-2.wangrx.sioc.ac.cn 客户端用户yzha ...
- 创业不要在IT业内创(市场太小,而且都喜欢自己折腾、没有花钱的习惯)
精神是好的.但是,我看了你的产品和网站:你选的创业方向基本是死路一条,我劝你该放弃就放弃.我判断你的思路还局限在IT行业内,创业不要在IT业内创,要走出去,睁开眼看看别人的世界,自己体会.我不是打击你 ...
- 你真的会玩SQL吗?透视转换
原文:你真的会玩SQL吗?透视转换 透视转换是一种行列互转的技术,在转过程中可能执行聚合操作,应用非常广泛. 本章与 你真的会玩SQL吗?数据聚合 内容比较重要,还涉及到 你真的会玩SQL吗?Case ...