[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 ...
随机推荐
- iOS 之 cocoapods安装与使用
我们都知道第三方库,一般使用cocoapods管理,cocoapods在我们IOS开发中有着很大的作用. 好了,现在看下它的安装步骤: 1.打开终端,输入 sudo gem install cocoa ...
- TRIGGERS_监测系统_原始数据表触发器—调用告警信息存储过程
//每次向originaldata表中插入数据就会触发该触发器 create or replace trigger originaldata_to_alarm after insert on ori ...
- 在函数中处理html点击事件在标签中增加属性值来解决问题。
- 50个必备的实用jQuery代码段+ 可以直接拿来用的15个jQuery代码片段
50个必备的实用jQuery代码段+ 可以直接拿来用的15个jQuery代码片段 本文会给你们展示50个jquery代码片段,这些代码能够给你的javascript项目提供帮助.其中的一些代码段是从j ...
- text-overflow 文字溢出时的设置
text-overflow : clip | ellipsis clip: 不显示省略标记(...),而是简单的裁切. ellipsis: 当对象内文本溢出时显示省略标记(...) 设置或检索是否使用 ...
- MyEclipse6.5安装SVN插件的三种方法
MyEclipse6.5安装SVN插件的三种方法 方法一.如果可以上网可在线安装 1. 打开Myeclipse,在菜单栏中选择Help→Software Updates→Find and Instal ...
- Effective Java2读书笔记-创建和销毁对象(二)
第3条:用私有构造器或者枚举类型强化Singleton属性 这一条,总体来说,就是讲了一个小技巧,将构造器声明为private,可以实现单例.具体有以下几种实现的方式. ①最传统的单例实现模式,可能有 ...
- 正则取页面图片URL和TABLE BackGround
/// <summary> /// 根据html文本返回url地址集合 /// </summary> /// <param name="sHtmlText&qu ...
- SVN的错误: working copy locked
提示:your working copy appears to be locked. run cleanup to amend the situation. 产生这种情况大多是因为上次svn命令执行失 ...
- cf479C Exams
C. Exams time limit per test 1 second memory limit per test 256 megabytes input standard input outpu ...