Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the exception specification of std::function's move constructor?

Tags:

c++

c++11

I've looked at cppreference.com and they seem to indicate no noexcept specification on std::function(std::function&&). This seems rather odd to me. Does the standard really not give a nothrow guarantee in this case?

like image 239
Puppy Avatar asked Nov 05 '12 23:11

Puppy


People also ask

Is move move constructor is noexcept?

Move constructors are usually noexcept, since otherwise they are unusable in any code that provides strong exception guarantee. In many implementations, is_nothrow_move_constructible also checks if the destructor throws because it is effectively noexcept(T(arg)).

Is a constructor obligated to move objects in a class?

It is not obligated to move anything, the class is not required to have a resource to be moved and a 'move constructor' may not be able to move a resource as in the allowable (but maybe not sensible) case where the parameter is a const rvalue reference (const T&&).

What is the use of move constructor in Java?

Thus, move constructor prevents unnecessarily copying data in the memory. Work of move constructor looks a bit like default member-wise copy constructor but in this case, it nulls out the pointer of the temporary object preventing more than one object to point to same memory location.

What is an exception specification in C++?

An exception specification is not part of a function's type. An exception specification may only appear at the end of the top-level function declarator in a declaration or definition of a function, pointer to function, reference to function, or pointer to member function. An exception specification cannot appear in a typedef declaration.


1 Answers

Quoting the standard (as you request):

C++11 §20.8.11.2.1/6 (from N3290):
function(function&& f);
template <class A> function(allocator_arg_t, const A& a, function&& f);
Effects: If !f, *this has no target; otherwise, move-constructs the target of f into the target of *this, leaving f in a valid state with an unspecified value.

So, sorry, no noexcept on the move constructor.

There is a related Defect Report 2062 which is still open, but it goes in the other direction, so to speak, namely that there is at least one noexcept that apparently should not be there, for whatever the rationale of that is…

It may be that the intent is to support callables that have throwing move constructors. But that is just speculation in the direction of rationalization. For example, imagine reallocation of the buffer in a vector of such function objects, where an attempt is made to move the originals, and where in the middle somewhere one of them throws (I think this was the original example by Abrahams et.al). Oh dang, they can't guaranteed be moved back, and neither can we go forward. So the reallocation fails, and the operation that caused the reallocation, fails, with the vector in an invalid state. A requirement of non-throwing move of the callable objects would have supported such general usage of function objects, including optimized vector reallocation (etc.). Which IMHO makes it doubtful that the intent really has been to make this trade-off.

like image 138
Cheers and hth. - Alf Avatar answered Sep 19 '22 19:09

Cheers and hth. - Alf