C++ -- noexcept关键字

C++ -- noexcept关键字

noexcept关键字

作用:告诉编译器,函数中不会发生异常,有利于编译器对程序做出更多的优化,比如避免生成处理异常的额外代码,减少程序的大小

例子

声明了noexcept和没有声明的同一段代码:

safeDivide 当除数为0时,会直接调用std::terminate()来中止程序而不是throw错误

// use of use of the noexcept specifier 
#include <iostream> 
using namespace std; 

// Function that may throw an exception 
int divide(int a, int b) 
{ 
	if (b == 0) { 
		throw runtime_error("Error: Division by zero"); 
	} 
	return a / b; 
} 

// Function that will not throw any exceptions (using 
// noexcept) 
double safeDivide(double a, double b) noexcept 
{ 
	if (b == 0) { 
		// In this case, std::terminate will be called if b 
		// is zero 
		cerr << "Error: Division by zero in safeDivide"
			<< std::endl; 
		terminate(); 
	} 
	return a / b; 
} 

int main() 
{ 
	cout << "noexcept value for divide(): "
		<< noexcept(divide(10, 0)) << "\n"; 

	cout << "noexcept value for safeDivide(): "
		<< noexcept(safeDivide(10.0, 0.0)); 

	return 0; 
}

Output:
noexcept value for divide(): 0
noexcept value for safeDivide(): 1

有条件的noexcept:

// C++ code to demonstrate the use of the 
// noexcept specifier with a function template 
#include <bits/stdc++.h> 
using namespace std; 

template <typename T> 
void process(const T& value) 
	noexcept(noexcept(declval<T>().size())) 
{ 
	// Try to call the size() member function of T 
	// If T's size() can throw, this function won't be 
	// noexcept for T 
	// If T's size() is noexcept, this 
	// function will be noexcept for T 
	cout << "Size: " << value.size() << endl; 
} 

// main function 
int main() 
{ 
	vector<int> numbers = { 1, 2, 3, 4, 5 }; 

	// Won't throw exceptions for std::vector 
	process(numbers); 
	// May throw exceptions for int 
	process(42); 

	return 0; 
}

什么时候使用noexcept?

  1. 确认不会抛出异常的函数:包括其调用的所有函数都不会抛出异常,那就可以标记其为noexcept ,适用于简单的访问函数、数学运算函数或者只包含基本类型操作的函数
  2. 移动构造函数移动赋值运算符:这些特殊成员函数应当尽可能地标记为noexcept。因为它们在资源管理(如智能指针的转移)中非常重要,且不应失败。如果移动操作可能抛出异常,容器和其他代码可能会回退到较慢的复制操作上,影响性能。

关于什么是移动构造函数以及移动赋值运算符,可以看这篇文章:
C++--移动构造函数以及移动赋值运算符

posted @ 2024-06-08 17:07  MrDC  阅读(171)  评论(0)    收藏  举报