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;