Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should I declare a move constructor without noexcept?

The standard doesn't enforce noexcept on move constructors. In what circumstances is it acceptable/neccesary for a move constructor to throw?

like image 509
Klaufir Avatar asked Nov 14 '14 02:11

Klaufir


People also ask

Is the default move constructor Noexcept?

Inheriting constructors and the implicitly-declared default constructors, copy constructors, move constructors, destructors, copy-assignment operators, move-assignment operators are all noexcept(true) by default, unless they are required to call a function that is noexcept(false) , in which case these functions are ...

What is the point of a move constructor?

A move constructor enables the resources owned by an rvalue object to be moved into an lvalue without copying.

Are move constructor automatically generated?

If a copy constructor, copy-assignment operator, move constructor, move-assignment operator, or destructor is explicitly declared, then: No move constructor is automatically generated. No move-assignment operator is automatically generated.

Does compiler provide default move constructor?

In C++, the compiler creates a default constructor if we don't define our own constructor. In C++, compiler created default constructor has an empty body, i.e., it doesn't assign default values to data members. However, in Java default constructors assign default values.


2 Answers

When you really have no choice. Most of the time your move constructor should be noexcept. And they are by default.

See this: http://www.codingstandard.com/rule/12-5-4-declare-noexcept-the-move-constructor-and-move-assignment-operator/

It is especially important to use noexcept for types that are intended to be used with the standard library containers. If the move constructor for an element type in a container is not noexcept then the container will use the copy constructor rather than the move constructor.

like image 82
Xaqq Avatar answered Oct 15 '22 07:10

Xaqq


The golden rule here is: It depends.

Here is an example where it might make sense:

// A lock_guard template somewhere up here...

template<typename mutex_t>
class shared_lock_guard
{
    mutex_t *mtx_ptr;

public:

    shared_lock_guard(lock_guard<mutex_t> &&other) :
    mtx_ptr{other.mtx_ptr}
    {
        if(this->mtx_ptr){

            // this might throw a system_error
            // if the syscall fails or if the
            // lock state was corrupted.
            //
            this->mtx_ptr->shared_relock();
        }

        other.mtx_ptr = nullptr;
    }

    // rest of implementation, etc...
};
like image 44
defube Avatar answered Oct 15 '22 06:10

defube