文章目录
前言
类型推断允许编译器自动推断出表达式的类型。类型推断有两个关键字:auto和decltype。
一、auto
关键字auto有多种不同的用法:
1.推断函数的返回类型。
2.结构化绑定。
3.推断表达式的类型。
4.推断非类型模板的类型。
5.简写函数模板的语法。
6.decltype(auto)
7.其他函数语法。
8.反省lambda表达式。
auto可用于告诉编译器,在编译期自动类型推断变量的类型。auto对复杂的类型更有用。
auto最简单的用法:
auto x { 1 };// type int
auto&
使用auto推断类型时去除了引用和const限定符。
const string message { "Test" };
const string& foo() { return message; }
auto f1 { foo() };
//f1 的类型是 string 而不是 const string&
因为auto去除了引用和const限定符,且f1是string类型。因此会建立一个副本。如果希望f1是一个const引用,可使用 const auto&:
const auto& f2 { foo() };
auto*
auto关键字可用于指针。
int i { 123 };
auto p { &i };
p的类型是 int*。在使用指针时,建议使用auto*语法,因为它可以更清楚的指出涉及指针。例如:
int i { 123 };
auto* p { &i };
此外,使用auto* 代替auto确实可以解决将auto、const和指针一起使用时的奇怪行为。假设:
const auto p1 { &i };
p1的类型是int* const而非const int*,将const 放在 auto后面,即 auto const p1 { &i }也无济于事,类型仍然是int* const。
当将const和auto*结合使用时,它的行为就会与期望的一样。例如:
const auto* p1 { &i };//int* const
auto* const p2 { &i };//const int*
const auto* const p3 { &i };//const int* const
拷贝列表初始化和直接列表初始化
有两种使用大括号初始化列表的初始化方式:
1.拷贝列表初始化:T obj = { arg1, arg2,…};
2.直接列表初始化:T obj { arg1, arg2,…};
与自动类型推断相结合,拷贝列表初始化和c++17引入的直接列表初始化之间就存在重要区别。
//拷贝列表初始化
auto a = { 11 };// initializer_list<int>
auto b = { 11, 22 };// initializer_list<int>
//直接列表初始化
auto c { 11 };// int
auto d { 11, 22 };// error.
以上代码在c++11/14中拷贝初始化列表和直接初始化列表都将推断出// initializer_list<>
二、decltype
关键字dectype把表达式作为实参,计算出该表达式的类型。例如:
int x { 123 };
decltype(x) y { 456 };
auto 和 decltye的区别在于,decltype为去除引用和const限定符。刚开始不会觉得decltype有多大价值。但是在模板环境中decltype会变得十分强大。