noexcept Operator in C++ 11
Last Updated :
15 Jul, 2024
Exception handling is an important concept in C++. Keywords like 'try', 'catch', and 'throw' are often associated with exception handling. Although these keywords are very powerful on their own we need another more efficient method to operate on them. Hence, noexcept operator was introduced in C++ 11.
noexcept Operator in C++
In C++, the noexcept operator is a compile-time operator that is used to check whether an expression will throw an exception. It checks the exception specification of the functions, but functions are not called or evaluated at runtime. The compiler checks the results based on the function declaration.
Also, when creating a function template, we can use noexcept
it to specify whether the function might throw exceptions or not for some specific data types.
Note: The noexcept operator does not actually evaluate the expression passed in the parameters. It simply checks whether the given expression will throw an exception or not.
Syntax of noexcept Operator
noexcept(expression)
Parameters
expression: It is the expression we want to evaluate.
Return Value
The function does not return any value. The result is true if the expression is guaranteed to not throw exceptions, otherwise, the result is false.
Example of noexcept Operator
Example 1:
C++
// C++ Program to demonstrate
// 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;
}
Outputnoexcept value for divide(): 0
noexcept value for safeDivide(): 1
Explanation of the above method:
In the above example, the function safeDivide() with noexcept specifier makes the compiler assume that it's a non-exception throwing function. The noexcept operator gets this and returns true, whereas for divide() there is no such specifier hence it value of noexcept operator is false.
If we remove the noexcept keyword from the safeDivide() then the value of the noexcept operator for the safeDivide() will be false. If a function with noexcept specifier has a potential exception during runtime then the compiler will show undefined behavior. Thus it is the job of the programmer to check function with zero exceptions is declared with noexcept specifier.
Example 2: C++ code to demonstrate the use of the noexcept
specifier with a function template
C++
// 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;
}
Output
./Solution.cpp: In instantiation of 'void process(const T&) [with T = int]':
./Solution.cpp:23:15: required from here
./Solution.cpp:5:6: error: request for member 'size' in 'std::declval<int>()', which is of non-class type 'int'
void process(const T& value)
^
./Solution.cpp: In instantiation of 'void process(const T&) [with T = int]':
./Solution.cpp:23:15: required from here
./Solution.cpp:5:6: error: request for member 'size' in 'std::declval<int>()', which is of non-class type 'int...
Explanation of the above method:
Fundamental types like int do not have a size() member function. The size() member function is specific to container types like std::vector, std::string, etc., where it returns the number of elements in the container. That is why it throws an exception.
When to use the noexcept operator?
- You have the guarantee that the function will not throw any exception in any case.
- You want to optimize the performance by allowing the compiler to skip the process of exception handling which leads to faster execution of the program.
When not to use the noexcept operator?
- Your function can throw exceptions, or if you're not sure about its exception safety.
- When you are dealing with destructors as noexcept destructor can lead to undefined behavior, when exceptions are thrown during object destruction.
Similar Reads
Noexcept Specifier in C++17 In C++ programming, error handling and exception safety are critical elements of writing sturdy and dependable code. The noexcept specifier is a feature delivered in C++11 and, in addition, more suitable in C++17 that facilitates developers control over exceptions and enhances the predictability of
6 min read
Operators in C++ C++ operators are the symbols that operate on values to perform specific mathematical or logical computations on given values. They are the foundation of any programming language.Example:C++#include <iostream> using namespace std; int main() { int a = 10 + 20; cout << a; return 0; }Outpu
9 min read
map::operator[] in C++ STL Maps are associative containers that store elements in a mapped fashion. Each element has a key value and a mapped value. No two mapped values can have same key values. map::operator[] This operator is used to reference the element present at position given inside the operator. It is similar to the
2 min read
list::operator= in C++ STL Lists are containers used in C++ to store data in a non contiguous fashion, Normally, Arrays and Vectors are contiguous in nature, therefore the insertion and deletion operations are costlier as compared to the insertion and deletion option in Lists. list::operator= This operator is used to assign n
2 min read
dot (.) operator in C++ The C++ dot (.) operator is used for direct member selection via the name of variables of type class, struct, and union. It is also known as the direct member access operator. It is a binary operator that helps us to extract the value of the function associated with a particular object, structure, o
3 min read