C++ 标准库 第二版 —— 第三章《 语言新特性》

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34536551/article/details/89173348

目录

nullptr 和 std::nullptr_t、以及与NULL 有何不同

auto 类型

初始化列表、窄化转换、使用 std::initializer_list (15P)

范围 for循环 (17P)

左值引用 、右值引用 和 标准库 Move 函数 (19P)

可变参数模板、模板别名 ( 27P)

Lambda 表达式 (28P)

decltype  关键字 ( 32P)

尾置返回类型 (32P)

*限定作用域的枚举类型(32P)

char16_t 和 char32_t、 long long 和 unsigned long long 、 std::nullptr_t 新的内存类型 (33P)

非类型模板参数、模板参数默认值、关键字Typename、成员模板、类模板嵌套 (33P)

函数 main 的定义 式 ( 37P)


nullptr 和 std::nullptr_t、以及与NULL 有何不同


  • NULL 是一个预处理变量,在头文件 cstdlib 中定义,可以为指针赋值,它的值本身就是0.
  • nullptr 是一种特殊类型的字符值,它可以转换为任意的其它指针类型,是不会被转换成任何其它整型的。该 关键字的类型为std :: nullptr_t,在<cstddef>中定义。
  • 如果用 字符值0初始化指针,表示将该指针初始化为空指针

用一个NULL 初始化指针时,预处理器会自动地将它替换为实际值。因此用NULL 初始化指针 和用0初始化指针是一样的。


auto 类型



int main()
{
	auto i; // 以auto声明的变量,其变量的类型会初动推导出来, 因此该变量必须被初始化
	static auto vat = 0.19; // 可以在 auto 前加 其它限定符

	vector<string> v;
	auto pos = v.begin(); // pos has type vector<string>::iterator

	system("pause");
	return 0;
}

初始化列表、窄化转换、使用 std::initializer_list (15P)


 使用 “ { }” 初始化话会强制执行所谓的值初始化,这意味着即使是内置类型的局部变量(没有被初始化),也会被0初始化(如果是指针,则为nullptr):

int i; // i has undefined value
int j{}; // j is initialized by 0
int* p; // p has undefined value
int* q{}; // q is initialized by nullptr
void print(std::initializer_list<int> vals)
{// initializer_list 中的元素永远是常量,我们不可以修改它的值
	for (auto p = vals.begin(); p != vals.end(); ++p) 
	{ // process a list of values
		std::cout << *p << "\n"; 
	}
}

int main()
{
	print({ 12,3,5,7,11,13,17 }); // pass a list of values to print(),而且传递的序列必须在 { } 号内
	system("pause");
	return 0;
}
class P
{
public:
	P(int i, int c)
	{
		cout << i << " " << c << endl << endl;
	}
	P(std::initializer_list<int> il)
	{
		
		for (auto p = il.begin(); p != il.end(); ++p) 
		{ 
			std::cout << *p << "\n";
		}
		cout << endl;
	}
};

int main()
{ 
  // 我们只能使用 ( )或  { } 初始化带有 explicit的构造函数,不能使用 = 初始化,但可以显式使用 = 初始化
	P p(77, 5); // calls P::P(int,int)
	P q{ 77,5 }; // calls P::P(initializer_list)
	P r{ 77,5,42 }; // calls P::P(initializer_list)
	P s = { 77,5 }; // calls P::P(initializer_list)
	system("pause");
	return 0;
}
class P
{
public:
	P(int a, int b) 
	{
		cout << " 调用的是带两个参数的构造函数!" << endl;
	}
	explicit P(int a, int b, int c) {
		cout << "调用的是 explicit 带有三个参数的构造函数!" << endl;
	}
};

int main()
{
    // 我们只能使用 ( )或  { } 初始化带有 explicit的构造函数,不能使用 = 初始化,但可以显式使用 = 初始化
	P x(77, 5); // OK,调用的是 p( int,int)
	P y{ 77,5 }; // OK,调用的是 p( int,int)
	P z{ 77,5,42 }; // OK,调用的是 explicit (int,int,int)
	P v = { 77,5 }; // OK (implicit type conversion allowed).调用的是 p( int,int)
	P w = { 77,5,42 }; // ERROR due to explicit (不允许隐式类型转换 ),复制列表初始化不能使用标记为“显式”的构造函数
	system("pause");
	return 0;
}
class P
{
public:
	P(int a, int b) 
	{
		cout << " 调用的是带两个参数的构造函数!" << endl;
	}
	explicit P(int a, int b, int c) {
		cout << "调用的是 explicit 带有三个参数的构造函数!" << endl;
	}
};
void fp(const P&)
{

}
int main()
{
	fp({ 47,11 }); // OK, implicit conversion of {47,11} into P
	fp({ 47,11,3 }); // ERROR due to explicit
	fp(P{ 47,11 }); // OK, explicit conversion of {47,11} into P
	fp(P{ 47,11,3 }); // OK, explicit conversion of {47,11,3} into P
	system("pause");
	return 0;
}

如果一个 explicit 构造函数 接受一个 初始化化列表,那么该构造函数不具有隐式转换的能力。


范围 for循环 (17P)



左值引用 、右值引用 和 标准库 Move 函数 (19P)



可变参数模板、模板别名 ( 27P)



Lambda 表达式 (28P)


int main()
{
	int x = 0;
	int y = 42;
	auto qqq = [x, &y] {
		std::cout << "x: " << x << std::endl;
		std::cout << "y: " << y << std::endl;
		++y; // OK
	};
	x = y = 77;
	qqq();
	qqq();
	std::cout << "final y: " << y << std::endl;
	std::cout << "final x: " << x<< std::endl;
	system("pause");
	return 0;
}

输出结果为:

x: 0
y: 77
x: 0
y: 78
final y: 79
final x: 77

y 以 通过 引用传递, 在 lambda 函数体中如果修改了其引用的对象的值,那么该值的变化也会影响到其引用的对象的值。

int main()
{
	int id = 0;
	auto f = [id]() mutable {
		std::cout << "id: " << id << std::endl;
		++id; // OK
	};
	id = 42;
	f();
	f();
	f();
	std::cout << id << std::endl;
	system("pause");
	return 0;
}

输出结果为:

id: 0
id: 1
id: 2
42

id 是通过值传递的,虽然我们显式使用 mutable 关键字指出可以修改被捕获变量的值,但是被修改的值并不会影响到 其外部的对象。

std::function<int(int, int)> returnLambda()
{
	return [](int x, int y) {
		return x * y;
	};
}
int main()
{
	auto lf = returnLambda();
	std::cout << lf(6, 7) << std::endl;
	system("pause");
	return 0;
}

decltype  关键字 ( 32P)


std::map<std::string,float> coll;
decltype(coll)::value_type elem; // elem 的类型是一个 pair< const string ,float >

尾置返回类型 (32P)



*限定作用域的枚举类型(32P)



char16_t 和 char32_t、 long long 和 unsigned long long 、 std::nullptr_t 新的内存类型 (33P)



非类型模板参数、模板参数默认值、关键字Typename、成员模板、类模板嵌套 (33P)


函数 main 的定义 式 ( 37P)


猜你喜欢

转载自blog.csdn.net/qq_34536551/article/details/89173348