modern effective C++ -- Deducint Types
1. 理解模板类型推导
1. expr是T&
template<typename T>
void f(T & param);
// 我们声明如下变量
int x = 27;
const int cx = x;
const int& rx = x;
函数调用时,推导出的Param和T的类型如下:
f(x); // T is int, param's type is int&
f(cx); // T is const int, param's type is const int&
f(rx); // T is const int, param's type is const int&
需要特别注明的是,通过T&
的方式传入数组,数组的大小信息不会丢失。
template<typename T>
void f(T& param);
int arr[10];
f(arr); // T is const int[10], param type is const int(&)[10]
在类型推导期间,数组和函数将退化为指针类型,除非他们是被初始化为引用。
2. expr是const T&
template<typename T>
void f(const T& param);
int x = 27;
const int cx = x;
const int& rx = x;
在进行类型推导的时候,rx的引用性被忽略了。
f(x); // T is int, param's type is const int&
f(cx); // T is int, param's type is const int&
f(rx); // T is int, param's type is const int&
3. param是一个指针类型
template<typename T>
void f(T* param); // param is now a pointer
int x = 27;
const int* px = &x;
f(&x); // T is int, param's type is int *
f(px); // T is const int, param's type is const int *
4. param是universial reference
template<typename T>
void f(T&& param); // param is now a universal reference
int x = 27;
const int cx = x;
const int rx = x;
f(x); // x is lvalue, so T is int&, param's type is also int&
f(cx); // cx is lvalue, so T is const int&, param's type is also const int&
f(rx); // rx is lvalue, so T is const int&, param's type is also const int&
f(27); // 27 is rvalue, so T is int, param's typs is int&&
5. param 既不是指针也不是引用
template<typename T>
void f(T param);
当ParamType既不是指针也不是引用的时候,我们按照值传递的方式进行处理。
需要举出一个有用的例子:
template<typename T>
void f(T param);
const char* const ptr = "hello world\n";
f(ptr); // param's type is const char*
2. 理解auto自动类型推导
auto 类型对象推导通常和模板类型推导是相同的。
例子:
const char name[] = "zhouyang";
auto arr1 = name; // arr1's type is const char*
auto& arr2 = name; // arr2's type is const char(&)[9]
void someFunc(int, double); // someFunc is a function
auto func1 = someFunc; // func1's type is void(*)(int, double)
auto& func2 = someFunc; // func2's type is void(&)(int, double)
唯一的例外是:使用auto和大括号进行初始化时,自动推导为std::initializer_list。并且,对于使用括号进行的初始化,模板类型推导会失败。
3. 理解decltype
decltype 一般情况下总是返回变量名或者表达式的类型而不做任何的修改。
const int i = 0; // decltype(i) is const int
bool f(const Widget& w) // decltype(w) is const Widget&
Widget W; // decltype(w) is Widget
在C++14中,提供了decltype(auto)的支持,它从初始化式子中推导类型,使用的是decltype的推导规则。
Widget w;
cosnt Widget& cw = w;
auto myWidget1 = cw; // myWidget1's type is Widget
decltype(auto) myWidget2 = cw; // decltype type deduction:
// myWidget2's type is const Widget&
// 注:可以在模板中使用
特例:
#include <iostream>
using namespace std;
int main()
{
int temp = 10;
decltype((temp)) temp1 = temp; // temp1's type is int&
temp1 = 1;
cout<< temp << endl;
return 0;
}
//输出 : 1
4. 了解如何查看推导出的类型
可以利用编译器诊断来完成。我们想要知道被推导出的类型,可以首先声明一个类模板,但是不定义它。那么编译器的出错信息会包含推导的类型信息。
template<typename T>
class TD;
通过编译器内置的宏定义,可以输出函数类型
#include <iostream>
#include <vector>
using namespace std;
void test_func(int)
{
#if defined(__GNUC__)
cout << __PRETTY_FUNCTION__ << endl;
#elif defined(_MSC_VER)
cout << __FUNCSIG__ << endl;
#endif
}
int main()
{
test_func(10);
return 0;
}
modern effective C++ -- Deducint Types的更多相关文章
- Item 15: 只要有可能,就使用constexpr
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 如果说C++11中有什么新东西能拿"最佳困惑奖" ...
- Item 21: 比起直接使用new优先使用std::make_unique和std::make_shared
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 让我们先从std::make_unique和std::make_s ...
- Item 20: 使用std::weak_ptr替换会造成指针悬挂的类std::shared_ptr指针
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 矛盾的是,我们很容易就能创造出一个和std::shared_ptr ...
- Item 19: 使用srd::shared_ptr来管理共享所有权的资源
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 使用带垃圾回收机制语言的程序员指出并嘲笑C++程序员需要遭受防止资 ...
- Item 18: 使用srd::unique_ptr来管理独占所有权的资源
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 当你需要一个智能指针的时候,std::unique_ptr通常是最 ...
- Item 17: 理解特殊成员函数的生成规则
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 C++的官方说法中,特殊成员函数是C++愿意去主动生成的.C++9 ...
- Item 16: 让const成员函数做到线程安全
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 如果我们在数学领域里工作,我们可能会发现用一个类来表示多项式会很方 ...
- Item 14: 如果函数不会抛出异常就把它们声明为noexcept
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 在C++98中,异常规范(exception specificat ...
- Item 13: 比起iterator优先使用const_iterator
本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 STL中的const_iterator等价于pointers-to ...
随机推荐
- gulp学习-metamask前端使用
https://www.gulpjs.com.cn/docs/getting-started/ ,这个是3.9.0版本 后面发现安装的版本是4.0.0,看下面这个: https://github.co ...
- npm和node的版本过低时的解决办法
npm版本过低时的解决办法npm全名Node Package Manager 1.配置源的三种方法:1).npmrc文件的作用,就是配置npm源:使用淘宝源的方法就是在文件.npmrc中加入下面的语句 ...
- dijkstra P4779 【模板】单源最短路径(标准版) 洛谷luogu
题目背景 2018 年 7 月 19 日,某位同学在 NOI Day 1 T1 归程 一题里非常熟练地使用了一个广为人知的算法求最短路. 然后呢? 100→60 Ag→Cu 最终,他因此没能与理想的大 ...
- <操作系统>内存管理
单道程序设计:内存被划分为两部分:一部分供操作系统使用,另一部分供当前正在执行的程序使用. 多道程序设计:内存中进一步细分用户部分,以满足多个进程的要求. 内存管理的需求: 重定位:程序从磁盘换入内存 ...
- 如何屏蔽在Skyline的TerraExplorer中加载Shape或者KML等数据时的缓冲提示信息
在使用TerraExplorer软件或者二次开发自定义打开FLY工程时,以及在已有的FLY工程中导入其他矢量数据,如SHP.WFS图层.KML图层时,总会看到类似下图的提示信息: 有些用户问,如何能屏 ...
- 2-(基础入门篇)Air202下载开发入门(给Air202下载第一个程序)
http://www.cnblogs.com/yangfengwu/p/8887933.html 资料链接 链接:https://pan.baidu.com/s/1-SRfsKGQ7rZVvFmp1O ...
- 源代码管理工具(下)-SVN目录结构
内容中包含 base64string 图片造成字符过多,拒绝显示
- RocketMQ阅读注意
1 队列个数设置 producer发送消息时候设置,特别注意:同一个topic仅当第一次创建的时候设置有效,以后修改无效,除非修改broker服务器上的consume.json文件,
- SpringBoot日记——ElasticSearch全文检索
看到标题的那一串英文,对于新手来说一定比较陌生,而说起检索,应该都知道吧. 这个ElasticSearch目前我们的首选,他主要有可以提供快速的存储.搜索.分析海量数据的作用.他是一个分布式搜索服务, ...
- [T-ARA][떠나지마][不要离开]
歌词来源:http://music.163.com/#/song?id=22704408 잊기엔 너무 사랑했나봐 [id-ggi-en neo-mu sa-lang-haen-na-bwa] 아직도 ...