can_throw oder nicht can_throw?



Ausnahmen sind Teil der C ++ - Sprache. Ein mehrdeutiger Teil davon. Jemand benutzt sie im Prinzip nicht. Es benutzt es überhaupt nicht. Vom Wort überhaupt. Aber nicht wir. Da wir sie für eine sehr nützliche Sache halten, erhöht sich die Zuverlässigkeit des Codes erheblich.



Leider können nicht alle Ausnahmen überall verwendet werden. Erstens sind Ausnahmen nicht frei und zweitens kann nicht jeder Code das Auftreten von Ausnahmen "überleben".



. , C++. , , C++ .



, noexcept. , , .



, C++, , .





C++ noexcept. noexcept / , / . , noexcept / , ( , swap, C- callback- ..).



, noexcept /. , - /, , . , :



void some_handler::on_read_result(
    const asio::error_code & ec,
    std::size_t bytes_transferred)
{
    if(!ec)
    {
        m_data_size = bytes_transferred;
        handle_data();
    }
    else
    {...}
}


handle_data , .



noexcept : / .



— , , . C++ - noexcept-. noexcept-. - :



void some_handler::on_read_result(
    const asio::error_code & ec,
    std::size_t bytes_transferred)
{
    noexcept
    {
        if(!ec)
        {
            m_data_size = bytes_transferred;
            handle_data();
        }
        else
        {...}
    }
}


. noexcept- noexcept-, . - , , .



, noexcept- C++ . , . . , .





, C++ , , . (callback-).



callback-, completion-handler- Asio. callback- , .. Asio . , completion-handler- — .



callback-, . , , .



callback-, Asio C- , try/catch, , :



void some_handler::on_read_result(
    const asio::error_code & ec,
    std::size_t bytes_transferred)
{
    try
    {
        handle_read_result(ec, bytes_transferred); //  .
    }
    catch(...)
    {
        //    "" .
    }
}


, , , ( ) callback try/catch handle_read_result. .



, , . .. , / , .



can_throw



can_throw, /. , can_throw, . /, can_throw.



, - callback- /, can_throw, .



, .. can_throw /. .. :



void some_handler::handle_read_result(
    can_throw_t can_throw,
    const asio::error_code & ec,
    std::size_t bytes_transferred)
{
    ... //      .
}

void some_handler::on_read_result(
    const asio::error_code & ec,
    std::size_t bytes_transferred)
{
    //     !
    handle_read_result(can_throw_t{}, ec, bytes_transferred);
}


, can_throw :



class can_throw_t
{
    friend class exception_handling_context_t;

    can_throw_t() noexcept = default;

public:
    ~can_throw_t() noexcept = default;

    can_throw_t( const can_throw_t & ) noexcept = default;
    can_throw_t( can_throw_t && ) noexcept = default;

    can_throw_t &
    operator=( const can_throw_t & ) noexcept = default;
    can_throw_t &
    operator=( can_throw_t && ) noexcept = default;
};


.. can_throw_t, " " (). , can_throw_t exception_handling_context_t:



class exception_handling_context_t
{
public:
    can_throw_t
    make_can_throw_marker() const noexcept { return {}; }
};


make_can_throw_marker()



void some_handler::on_read_result(
    const asio::error_code & ec,
    std::size_t bytes_transferred)
{
    try
    {
        exception_handling_context_t ctx;
        handle_read_result(ctx.make_can_throw_marker(), ec, bytes_transferred);
    }
    catch(...)
    {}
}


, exception_handling_context_t try/catch. . , wrap_throwing_action, , try, . - :



class can_throw_t
{
    //   can_throw  
    //   wrap_throwing_action.
    template<typename Lambda>
    friend void wrap_throwing_action(Lambda &&);

    can_throw_t() noexcept = default;

public:
    ... //    .
};

template< typename Lambda >
void wrap_throwing_action(Lambda && lambda)
{
    try
    {
        lambda(can_throw_t{});
    }
    catch(...)
    {}
}


.



can_throw_t exception_handling_context_t.



, callback- , , try.



, - / callback-, . , try . exception_handling_context_t :



some_handler::some_handler(
    std::vector<std::byte> initial_data,
    std::size_t initial_data_size)
    : m_data{std::move(initial_data)}
    , m_data_size{initial_data_size}
{
    exception_handling_context_t ctx;
    handle_data(ctx.make_can_throw_marker());
}
...
void some_handler::handle_read_result(
    can_throw_t can_throw,
    const asio::error_code & ec,
    std::size_t bytes_transferred)
{
    if(!ec)
    {
        m_data_size = bytes_transferred;
        handle_data(can_throw);
    }
    else
    {
        ...
    }
}
...
void some_handler::handle_data(can_throw_t)
{
    ... //   .
}


, catch: - , - "" ( callback- , ). wrap_throwing_action wrap_throwing_action.





" " . . : , . /, , , /.



, , - .



-, can_throw. .., , , . , , / . , , , .



-, can_throw . , , . .. callback-, can_throw , . can_throw callback- — callback- ( , callback-).



can_throw , can_throw . , can_throw . , , — .



, , , can_throw .





, , C++.



. , - ( RSDN) 15 . , , - .



, ++. can_throw. , :( .




All Articles