C++ program that demonstrates the use of lambda expressions for numerical integration and exception handling using std::exception_ptr. Here's the implementation:
algorithm, auto, command_line_arguments, exception, iostream, namespace, range-based, sstream, std::cin, std::cout, std::cerr, std::exception, std::ifstream, std::ofstream, stdexcept, throw, vector
#include <iostream>
#include <functional>
#include <cmath>
#include <exception>
#include <stdexcept>
// Trapezoidal rule implementation using lambda
double trapezoidal_rule(std::function<double(double)> f, double a, double b, int n) noexcept {
try {
if (n <= 0) {
throw std::invalid_argument("Number of subdivisions must be positive");
}
double h = (b - a) / n;
double sum = 0.5 * (f(a) + f(b));
for (int i = 1; i < n; ++i) {
sum += f(a + i * h);
}
return h * sum;
} catch (...) {
return std::numeric_limits<double>::quiet_NaN();
}
}
// Function to safely execute integration and handle exceptions
std::pair<double, std::exception_ptr> safe_integrate(std::function<double(double)> f, double a, double b, int n) {
std::exception_ptr eptr;
double result = 0.0;
try {
result = trapezoidal_rule(f, a, b, n);
if (std::isnan(result)) {
throw std::runtime_error("Integration failed");
}
} catch (...) {
eptr = std::current_exception();
}
return {result, eptr};
}
int main() {
// Define the function to integrate using a lambda expression
auto f = [](double x) { return x * x; };
double a = 0.0;
double b = 1.0;
int n = 1000;
auto [result, eptr] = safe_integrate(f, a, b, n);
if (eptr) {
try {
std::rethrow_exception(eptr);
} catch (const std::exception& e) {
std::cout << "Exception caught: " << e.what() << std::endl;
}
} else {
std::cout << "Integration result: " << result << std::endl;
}
// Test with invalid input
std::tie(result, eptr) = safe_integrate(f, a, b, -1);
if (eptr) {
try {
std::rethrow_exception(eptr);
} catch (const std::exception& e) {
std::cout << "Exception caught: " << e.what() << std::endl;
}
} else {
std::cout << "Integration result: " << result << std::endl;
}
return 0;
}
This program demonstrates the following concepts:
auto f = [](double x) { return x * x; };
This allows for inline definition of the function without needing a separate function declaration.
std::exception_ptr and noexcept:
trapezoidal_rule
function is marked as noexcept
, indicating that it will handle all exceptions internally.std::exception_ptr
in the safe_integrate
function to capture any exceptions that occur during integration.The main function demonstrates how to safely handle these exceptions using std::rethrow_exception
.
Numerical Integration:
It handles potential errors such as invalid input (negative number of subdivisions).
Error Handling:
std::numeric_limits<double>::quiet_NaN()
to indicate integration failure in a way that can be checked later.This implementation provides a robust framework for numerical integration that can handle errors gracefully, which is crucial in scientific computing applications where reliability and error recovery are important.
std::exception_ptr
in C++noexcept
with lambda functions