Does an exception use move semantics when thrown in C++11?

前端 未结 3 1916
清酒与你
清酒与你 2020-12-10 12:01

http://www.drdobbs.com/cpp/practical-c-error-handling-in-hybrid-env/197003350?pgno=4

In this article Herb Sutter explains that throwing an exception requires a copy

3条回答
  •  爱一瞬间的悲伤
    2020-12-10 12:18

    • Upon throw expression, a copy of the exception object always needs to be created as the original object goes out of the scope during the stack unwinding process.
    • During that initialization, we may expect copy elision (see this) – omits copy or move constructors (object constructed directly into the storage of the target object).
    • But even though copy elision may or may not be applied you should provide proper copy constructor and/or move constructor which is what C++ standard mandates(see 15.1). See below compilation error for reference.

    But modern C++ provides more feature: "Moving safely with move semantics & exception"

    struct demo
    {
        demo() = default;
        demo(const demo &) { cout << "Copying\n"; }
        // Exception safe move constructor
        demo(demo &&) noexcept { cout << "Moving\n"; }
    private:
        std::vector    m_v;
    };
    int main()
    {
        demo obj1;
        if (noexcept(demo(std::declval()))){  // if moving safe
            demo obj2(std::move(obj1));             // then move it
        }
        else{
            demo obj2(obj1);                        // otherwise copy it
        }
        demo obj3(std::move_if_noexcept(obj1));     // Alternatively you can do this----------------
        return 0;
    }
    
    • We can use noexcept(T(std::declval())) to check if T’s move constructor exists and is noexcept in order to decide if we want to create an instance of T by moving another instance of T (using std::move).
    • Alternatively, we can use std::move_if_noexcept, which uses noexcept operator and casts to either rvalue or lvalue. Such checks are used in std::vector and other containers.
    • This will be useful while you are processing critical data which you don't want to lose. For example, we have critical data received from the server that we do not want to lose it at any cost while processing. In such a case, we should use std::move_if_noexcept which will move ownership of critical data only and only if move constructor is exception-safe.

    From: 7 best practices for exception handling in C++

提交回复
热议问题