C++14
Lambda 函数
C++14 的泛型 Lambda 使编写如下语句成为可能:
auto lambda = [](auto x, auto y) {return x + y;};
而另一方面,C++11 要求 Lambda 参数使用具体的类型声明,比如:
auto lambda = [](int x, int y) {return x + y;};
此外,新标准中的 std::move 函数可用于捕获 Lambda 表达式中的变量,这是通过移动对象而非复制或引用对象实现的:
std::unique_ptr ptr (new int (10));
auto lambda = [value = std::move (ptr)] {return *value;};
int a = 2;
[a = sin(a)]()
{
cout << cos(a) << endl; //0.6143
}();
cout << a << endl; //2
cout << cos(a) << endl;//-0.416147
C++14中的这个新特性允许了在捕获列表中定义前面没有出现过的变量,但必须赋予一个值,并且不使用类型说明符和auto,类型由编译器自动推断:
int a = 2;
[b = tan(a)]() //b是新定义的变量,类型自动推断为double,值为tan(2)
{
cout << b << endl;
}();
constexpr
- 在C++11 中,使用 constexpr 声明的函数可以在编译时执行,生成一个值,用在需要常量表达式的地方,比如作为初始化模板的整形参数。
- C++11 的 constexpr 函数只能包含一个表达式,C++14 放松了这些限制,支持诸如 if 和 switch 等条件语句,支持循环,其中包括基于区间(range)的 for 循环。
变量模板
//代码5.1
#include <iostream>
#include <string>
using namespace std;
template <typename T>
T var; //声明变量模板
void assign() //为模板的相应变量赋值
{
var<int> = 7;
var<double> = 3.14;
var<char> = '$';
var<string> = "这是一个字符串";
}
void get_address() //获取模板的相应变量的地址
{
int* pi = &var<int>;
double* pd = &var<double>;
char* pc = &var<char>;
string* ps = &var<string>;
cout << pi << " " << pd << " " << static_cast<void*>(pc) << " " << ps << endl;
}
void output() //输出模板的相应变量
{
cout << var<int> << endl << var<double> << endl << var<char> << endl << var<string> << endl;
}
int main()
{
get_address();
output();
assign();
get_address();
output();
return 0;
}
结果分析:
- 这段代码使用template T var;
- 语句声明了一个(全局的)变量模板,并在assign函数中进行了赋值。由get_address的输出结果可知,var变量模板的四个实例var, var, var, var的地址不同,说明它们是四个不同的变量。
- 使用变量模板的好处和使用函数模板一样,对于需要重复定义用途类似,但类型不同的变量,可以减少重复代码量,不必重复定义形如var_int, var_double…之类的变量。
数值表达
1. 二进制字面值表示
- 在一些程序中会使用一个整数的若干二进制位来表示表示状态。
- 过去,我们只能用十六进制,四位四位地表示各位。
- 直接从十六进制数读出每一个二进制位还是很不直观的。
- 因此,直接用二进制位来表示会更直观一些。
- 在C++14中,引入了二进制字面值表示,以0b开头的是二进制数:
//下面的 i1 == i2
int i1 = 0x78D;
int i2 = 0b011110001101;
2.数字分位符
上面的二进制数还是不够易读,主要原因是数字还是太长了,如果能每几位划分一下,就更易读了。在C++14中,可以使用单引号 ' 作为分位符:
int i2 = 0b0111'1000'1101;
在C++14中,任何数,包括浮点数,也包括任何进制的数,都可以使用分位符。而且,位数可以任意划分,不一定非得等长:
int i3 = 13'22'3;
int i4 = 0x3F'4D'2C'1B;
float f1 = 6.6'26e+3'3;
float f2 = 3.1'415'9265'3'589'79;