常用C++20技术点

概述常用C++20技术点

一、Importing Modules 导入模块

c++ 20的一个较大的新特性是对模块的支持,它取代了所谓头文件的旧机制

import <iostream>;  //C++20 导入模块
#include <iostream> //传统包含头文件的方式 

VS2022 支持导入模块的设置

  1. 属性-》属性配置-》常规-》C++语言标准-》预览最新(/std::C++latest)
  2. 属性-》属性配置-》C/C+±》常规-》扫描以查找依赖关系-》是
  3. 属性-》属性配置-》C/C+±》语言-》启用实验性的C++标准库模块

二、推荐使用 format 格式化输出

import <format>;
std::cout << std::format("hello world {}",100) << std::endl;
int uninitializedInt;
int initializedInt{ 7 };			//统一的变量初始化
cout << format("{} is a random value", uninitializedInt) << endl;
cout << format("{} was assigned an initial value", initializedInt) << endl;

三、Numerical Limits 数值范围

cout << "int:\n";
cout << format("Max int value: {}\n", numeric_limits<int>::max());
cout << format("Min int value: {}\n", numeric_limits<int>::min());
cout << format("Lowest int value: {}\n", numeric_limits<int>::lowest());
cout << "\ndouble:\n";
cout << format("Max double value: {}\n", numeric_limits<double>::max());
cout << format("Min double value: {}\n", numeric_limits<double>::min());
cout << format("Lowest double value: {}\n", numeric_limits<double>::lowest());

四、casting 强制类型转换

float myFloat { 3.14f };
int i1 { (int)myFloat }; // method 1   C语言方式 不推荐
int i2 { int(myFloat) }; // method 2   不推荐
int i3 { static_cast<int>(myFloat) }; // method 3 推荐使用

五、Enumerated Types 枚举类型

旧式枚举不是强类型的,这意味着它们不是类型安全的。它们总是被解释为整数,可能无意中比较来自完全不同枚举类型的枚举值,或者将错误枚举类型的枚举值传递给函数。

//老式 没有范围限定
enum PieceTypeOld { PieceTypeKing, PieceTypeQueen, PieceTypeRook, PieceTypePawn };
PieceTypeOld old = PieceTypeKing;

//C++20  有范围限定 安全
enum class PieceTypeNew
{
    King = 1,
    Queen,
    Rook = 10,
    Pawn
};
using PieceTypeNew::King;
PieceTypeNew piece1{ King };
PieceTypeNew piece2{ PieceTypeNew::Queen };

六、自定义模块

//文件名也可以.cppm 后缀
export module Employee;

export struct Employee
{
	char firstInitial;
	char lastInitial;
	int employeeNumber;
	int salary;
};
import <iostream>;   //导入模块
import <format>;

//导入自定义模块不需要尖括号
import Employee;

using namespace std;

int main()
{
	//自定义导出模块
	Employee anEmployee;
	anEmployee.firstInitial = 'J';
	anEmployee.lastInitial = 'D';
	anEmployee.employeeNumber = 42;
	anEmployee.salary = 80000;
	// Output the values of an employee.
	cout << format("Employee: {}{}", anEmployee.firstInitial,
		anEmployee.lastInitial) << endl;
	cout << format("Number: {}", anEmployee.employeeNumber) << endl;
	cout << format("Salary: ${}", anEmployee.salary) << endl;
}

七、if/switch

/**********************************************************/
//传统if语句
if (i > 4) 
{
 // Do something.
} else if (i > 2) 
{
 // Do something else.
} else 
{
 // Do something else.
}

//if语句的初始化列表形式
if (<initializer>; <conditional_expression>) 
{
 	<if_body>
} else if (<else_if_expression>) {
 	<else_if_body>
} else 
{
 	<else_body>
}

if (Employee employee { getEmployee() }; employee.salary > 1000) 
{
    
}

/***************************************************************/
//传统switch语句
switch (menuItem) 
{
     case OpenMenuItem:
     // Code to open a file
     break;
     case SaveMenuItem:
     // Code to save a file
     break;
     default:
     // Code to give an error message
     break;
}
//C++20
switch (<initializer>; <expression>) 
{ 
    <body> 
}

八、Three-Way Comparisons 三元操作符 <=>

/*******************************三元操作符*********************************/
// <=> 又被叫做宇宙飞船操作符(形状像是宇宙飞船)
//strong_ordering::less: First operand less than second
//strong_ordering::greater : First operand greater than second
//strong_ordering::equal : Equal operands
int i{ 11 };
strong_ordering result{ i <=> 0 };

if (result == strong_ordering::less) { cout << "less" << endl; }
if (result == strong_ordering::greater) { cout << "greater" << endl; }
if (result == strong_ordering::equal) { cout << "equal" << endl; }

if (is_lt(result)) { cout << "less" << endl; }
if (is_gt(result)) { cout << "greater" << endl; }
if (is_eq(result)) { cout << "equal" << endl; }

九、Attributes 属性

1. [[nodiscard]]

告诉编译器 这个函数返回值必须被使用,否则编译发出警告 warning C4834: 放弃具有 “nodiscard” 属性的函数的返回值
此属性通常用来修饰返回错误码的函数(警告这个返回值不能忽视)

import <iostream>;   //导入模块
using namespace std;

//[[nodiscard]] 属性告诉编译器 这个函数返回值必须被使用,否则编译发出警告 warning C4834: 放弃具有 "nodiscard" 属性的函数的返回值
[[nodiscard]] int func()
{
	return 42;
}
//C++20之后可以自定义警告消息
[[nodiscard("这个返回值不能忽视")]] int func2()
{
	return 42;
}

int main()
{
	func();
    func2();
}

2. [[maybe_unused]]

告诉编译器在某些东西未使用时不用发出警告

import <iostream>;   //导入模块
using namespace std;

int func2(int param1,[[maybe_unused]]int param2)
{
	return 42;
}

int main()
{
    func2();
}

3. [[noreturn]]

告诉编译器不会将控制权返回到调用站点

import <iostream>;   //导入模块
import <format>;
using namespace std;

//如果不加 [[noreturn]] 发出警告 warning C4715: “isFeatureLicensed”: 不是所有的控件路径都返回值
[[noreturn]] void forceProgramTermination()
{
	std::exit(1); 
}
bool isDongleAvailable()
{
	bool isAvailable{ false };
	return isAvailable;
}
bool isFeatureLicensed(int featureId)
{
	if (!isDongleAvailable()) {
		forceProgramTermination();
	}
	else {
		bool isLicensed{ featureId == 42 };
		return isLicensed;
	}
}


int main()
{
	//[[noreturn]]
	bool bLicense{ isFeatureLicensed(42) };
}

4. [[deprecated]]

可以用来标记某些东西已被弃用,这意味着您仍然可以使用它,但不鼓励使用它,参数可以指定弃用原因

[[deprecated("Unsafe method, please use xyz")]] void func();

5. [[likely]] [[unlikely]]

帮助编译器优化代码,多用于if switch 分支中

int value { /* ... */ };
if (value > 11) [[unlikely]] 
{ 
    /* Do something ... */ 
}
else 
{ 
    /* Do something else... */ 
}
switch (value)
{
     [[likely]] case 1:
     // Do something ...
     break;
     case 2:
     // Do something...
     break;
     [[unlikely]] case 12:
     // Do something...
     break;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值