条款二 了解auto类型推断

基础知识

除了一处例外,auto的类型推断与template一样。存在一个直接的从template类型推断到auto类型推断的映射

三类情况下的推断如下所示:

// case 1
const auto& rx = x; // rx -> int // case 2
auto&& uref1 = x; // uref1 -> int&
auto&& uref2 = cx; // uref2 -> const int&
auto&& uref3 = ; // uref3 -> int&& // case 3
auto x = ; // x -> int
const auto cx = x; // x -> int

对于数组和函数,有如下推断:

const char name[] = "R. N. Briggs";
auto arr1 = name; // arr1 -> const char*
auto& arr2 = name; // arr2 -> const char(&)[13] void someFunc(int, double);
auto func1 = someFunc; // func1 -> void (*)(int, double)
auto& func2 = someFunc; // func2 -> void (&)(int, double)

但是在使用初始化列表(std::initializer_list)的情况下,auto的类型推断会有问题

auto x = ; // x1 -> int
auto x2(); // x2 -> int
auto x3 = {}; // x3 -> std::initializer_list<int>
auto x4{}; // x4 -> std::initializer_list<int>

列表初始化是auto与template类型推断的唯一区别,template函数推断中不能使用列表形式的初始化{}

auto x = {, , };
template<typename T>
void f(T param);
f({, , }); // wrong! template<typename T>
void f(std::initializer_list<T> initList);
f({, , }); // T -> int, initList -> std::initializer_list<int>

C+14可以使用auto来推断函数返回类型,并且lambda可以在形参声明中使用auto,但是此处的auto使用template类型推断而非auto类型推断,所以返回列表初始化将报错

auto createInitList() {
return {, , };
} // error! std::vector<int> v;
auto resetV = [&v](const auto& newValue) {v = newValue};
resetV({, , }) // error!

总结

  • auto类型推断总是和template类型推断一样,但是auto类型推断把列表初始化解析成std::initializer_list,template类型推断则不然
  • 在函数返回类型以及lambda形参中的auto,采用template类型推断而非auto类型推断

[Effective Modern C++] Item 2. Understand auto type deduction - 了解auto类型推断的更多相关文章

  1. [Effective Modern C++] Item 1. Understand template type deduction - 了解模板类型推断

    条款一 了解模板类型推断 基本情况 首先定义函数模板和函数调用的形式如下,在编译期间,编译器推断T和ParamType的类型,两者基本不相同,因为ParamType常常包含const.引用等修饰符 t ...

  2. [Effective Modern C++] Item 3. Understand decltype - 了解decltype

    条款三 了解decltype 基础知识 提供一个变量或者表达式,decltype会返回其类型,但是返回的内容会使人感到奇怪. 以下是一些简单的推断类型: ; // decltype(i) -> ...

  3. [Effective Modern C++] Item 5. Prefer auto to explicit type declarations - 相对显式类型声明,更倾向使用auto

    条款5 相对显式类型声明,更倾向使用auto 基础知识 auto能大大方便变量的定义,可以表示仅由编译器知道的类型. template<typename It> void dwim(It ...

  4. [Effective Modern C++] Item 6. Use the explicitly typed initializer idiom when auto deduces undesired types - 当推断意外类型时使用显式的类型初始化语句

    条款6 当推断意外类型时使用显式的类型初始化语句 基础知识 当使用std::vector<bool>的时候,类型推断会出现问题: std::vector<bool> featu ...

  5. [Effective Modern C++] Item 4. Know how to view deduced types - 知道如何看待推断出的类型

    条款四 知道如何看待推断出的类型 基础知识 有三种方式可以知道类型推断的结果: IDE编辑器 编译器诊断 运行时输出 使用typeid()以及std::type_info::name可以获取变量的类型 ...

  6. [Effective Modern C++] Item 7. Distinguish between () and {} when creating objects - 辨别使用()与{}创建对象的差别

    条款7 辨别使用()与{}创建对象的差别 基础知识 目前已知有如下的初始化方式: ); ; }; }; // the same as above 在以“=”初始化的过程中没有调用赋值运算,如下例所示: ...

  7. Effective Modern C++ Item 27:重载universal references

    假设有一个接收universal references的模板函数foo,定义如下: template<typename T> void foo(T&& t) { cout ...

  8. Effective Modern C++ Item 37:确保std::thread在销毁时是unjoinable的

    下面这段代码,如果调用func,按照C++的标准,程序会被终止(std::terminate) void func() { std::thread t([] { std::chrono::micros ...

  9. 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 ...

随机推荐

  1. CSS 设计彻底研究(五)文字与图像

    第五章 文字与图像 5.1.2 设置字体 通过font-family属性设置字体.可以声明多种字体,字体之间用逗号分隔开.如一些字体名称中间有空格,需用双引号将其引起来,使浏览器知道这是一种字体的名称 ...

  2. SPOJ 1811 Longest Common Substring (后缀自动机第一题,求两个串的最长公共子串)

    题目大意: 给出两个长度小于等于25W的字符串,求它们的最长公共子串. 题目链接:http://www.spoj.com/problems/LCS/ 算法讨论: 二分+哈希, 后缀数组, 后缀自动机. ...

  3. 关于取数组地址的识记(&s+1,s+1,&s[0]+1)

    #include <stdio.h> #include <malloc.h> int main() { ', 'o'}; ); printf(]); ]+); printf(] ...

  4. winform 读取保存配置文件

    原文连接: public static string fileName = System.IO.Path.GetFileName(Application.ExecutablePath);        ...

  5. ActionSupport.getText()方法 以及 js中:<s:text name="" />

    下面略述com.opensymphony.xwork2.ActionSupport.getText()方法 public String getText(String aTextName) 说明:Get ...

  6. css使用技巧

    1) 网站上经常会出现用户输入一大段字符和字母以至于文字无法正常折行,把版式破坏,这样我们就要参考以下样式:word-wrap:break-word; overflow:hidden; 当然必须得有宽 ...

  7. dede调用时间大全标签,不同格式!

    [field:pubdate function="MyDate('Y-m-d',@me)"/]2013-12-17[field:pubdate function=MyDate('m ...

  8. 摆方块(贪心)P1087

    描述 给你一个n*n的方格,每个方格里的数必须连续摆放如 1      2 4      3 ,下图为不连续的,请输出从左上角到右下角的对角线上的最大和 1       2 3       4 输入 ...

  9. Delphi中的异常处理(10种异常来源、处理、精确处理)

    一.异常的来源 在Delphi应用程序中,下列的情况都比较有可能产生异常. 1.文件处理 2.内存分配 3.windows资源 4.运行时创建对象和窗体 5.硬件和操作系统冲突 6.网络问题 7.数据 ...

  10. C# Cookie编程

    Cookie,他最早出现是在Netscape Navigator 2.0中.Cookie其实就是由Web服务器创建的.将信息存储在机上的文件.那么为什么Web服务器要在客户机上面创建如此文件?这是因为 ...