Namespaces
Variants

cpp/error/rethrow if nested: Difference between revisions

From cppreference.com
Space Mission (talk | contribs)
m Notes: +FMT: P3068.
 
(15 intermediate revisions by 8 users not shown)
Line 1: Line 1:
{{cpp/title|rethrow_if_nested}}
{{cpp/title|rethrow_if_nested}}
{{cpp/error/sidebar}}
{{cpp/error/}}
 
{{|header=exception|=c++11|
{{ddcl | header=exception | notes={{mark since c++11}} |
template< class E >
template< class E >
void rethrow_if_nested( const E& e );
void rethrow_if_nested( const E& e );
}}
}}


If {{tt|E}} is a type that is unambiguously derived from {{c|std::nested_exception}}, extracts and throws the nested exception as if by calling {{c|dynamic_cast<const std::nested_exception&>(e).rethrow_nested()}}. Otherwise, does nothing.
If {{tt|E}} is a type{{|std::nested_exception}},
 
 
{{|
dynamic_cast<const std::nested_exception>(e)
rethrow_nested()
}}


===Parameters===
===Parameters===
{{param list begin}}
{{begin}}
{{param list item | e | the exception object to rethrow}}
{{|e|the exception object to rethrow}}
{{param list end}}
{{end}}


===Return value===
===
(none)
 
value==
 
=
 
()
 
 


===Example===
===Example===
{{cpp/error/exception/example_nested_exception}}
{{cpp/error/example_nested_exception}}


===See also===
===See also===
{{dcl list begin}}
{{begin}}
{{dcl list template | cpp/error/exception/dcl list nested_exception}}
{{|cpp/error/nested_exception}}
{{dcl list template | cpp/error/exception/dcl list throw_with_nested}}
{{|cpp/error/throw_with_nested}}
{{dcl list end}}
{{end
 
}}

Latest revision as of 20:33, 24 November 2024

 
 
 
Defined in header <exception>
template< class E >
void rethrow_if_nested( const E& e );
(since C++11)
(constexpr since C++26)

If E is not a polymorphic class type, or if std::nested_exception is an inaccessible or ambiguous base class of E, there is no effect.

Otherwise, performs

if (auto p = dynamic_cast<const std::nested_exception*>(std::addressof(e)))
    p->rethrow_nested();

Parameters

e - the exception object to rethrow

Notes

Unlike many related functions, this function is not intended to be called with a std::exception_ptr but rather an actual exception reference.

Feature-test macro Value Std Feature
__cpp_lib_constexpr_exceptions 202411L (C++26) constexpr for exception types

Possible implementation

namespace details
{
    template<class E>
    struct can_dynamic_cast
        : std::integral_constant<bool,
              std::is_polymorphic<E>::value &&
              (!std::is_base_of<std::nested_exception, E>::value || 
                std::is_convertible<E*, std::nested_exception*>::value)
          > {};

    template<class T>
    void rethrow_if_nested_impl(const T& e, std::true_type)
    {
        if (auto nep = dynamic_cast<const std::nested_exception*>(std::addressof(e)))
            nep->rethrow_nested();
    }

    template<class T>
    void rethrow_if_nested_impl(const T&, std::false_type) {}
}

template<class T>
void rethrow_if_nested(const T& t)
{
    details::rethrow_if_nested_impl(t, details::can_dynamic_cast<T>());
}

Example

Demonstrates construction and recursion through a nested exception object.

#include <exception>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <string>

// prints the explanatory string of an exception. If the exception is nested,
// recurses to print the explanatory string of the exception it holds
void print_exception(const std::exception& e, int level =  0)
{
    std::cerr << std::string(level, ' ') << "exception: " << e.what() << '\n';
    try
    {
        std::rethrow_if_nested(e);
    }
    catch (const std::exception& nestedException)
    {
        print_exception(nestedException, level + 1);
    }
    catch (...) {}
}

// sample function that catches an exception and wraps it in a nested exception
void open_file(const std::string& s)
{
    try
    {
        std::ifstream file(s);
        file.exceptions(std::ios_base::failbit);
    }
    catch (...)
    {
        std::throw_with_nested(std::runtime_error("Couldn't open " + s));
    }
}

// sample function that catches an exception and wraps it in a nested exception
void run()
{
    try
    {
        open_file("nonexistent.file");
    }
    catch (...)
    {
        std::throw_with_nested(std::runtime_error("run() failed"));
    }
}

// runs the sample function above and prints the caught exception
int main()
{
    try
    {
        run();
    }
    catch (const std::exception& e)
    {
        print_exception(e);
    }
}

Possible output:

exception: run() failed
 exception: Couldn't open nonexistent.file
  exception: basic_ios::clear

See also

a mixin type to capture and store current exceptions
(class) [edit]
throws its argument with std::nested_exception mixed in
(function template) [edit]