Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which std types are guaranteed to be empty/null after being used as arg in move constructor

I know shared_ptr, unique_ptr, weak_ptr are guaranteed to be empty after used as RVR argument in the constructor of the same type, but I wonder does standard specifies this for some other std:: types beside the ones I mentioned.

Please note that I know that elements after move are left in valid but unspecified state, I am here interested for which types state is specified.

like image 488
NoSenseEtAl Avatar asked Jan 13 '16 16:01

NoSenseEtAl


2 Answers

Types leaving moved-from objects in "empty" state are smart pointers, locks ([thread.lock.unique.cons]/21, [thread.lock.shared.cons]/21), file streams ([filebuf.cons]/(4.2)), futures ([futures.unique_future]/(8.2), [futures.shared_future]/10), promises ([futures.promise]/6), packaged tasks ([futures.task]/7), threads ([thread.thread.constr]/10), …

By contrast, templates leaving the moved-from objects with unspecified values are function ([func.wrap.func.con]/6), basic_regex ([re.regex.construct]/13), basic_string ([string.cons]/2), containers…

like image 129
Columbo Avatar answered Sep 21 '22 23:09

Columbo


A rule of thumb

As a rule of thumb: The move-only types or types with shared reference semantics leave their moved-from object in an empty state. All other types leave unspecified values.

Move-only types

Move-only types (which leave moved-from objects in an empty state) are std::unique_lock, std::thread, std::promise, std::packaged_task, std::future, basic_filebuf, std::basic_ifstream, std::basic_ofstream, std::basic_fstream, std::shared_lock and std::unique_ptr.

Shared reference semantics

Types with shared reference semantics are std::shared_future, and of course std::shared_ptr and std::weak_ptr. These leave their moved-from objects also in an empty state.

A notable exception

As I went through the standard library, I found std::stringstream and its input-only and output-only siblings (std::istringstream and std::ostringstream) as a notable exception. These classes are move-only, but nothing is being told about the moved-from object upon move-construction. Therefore, the valid-but-unspecified-rule applies. As you see, it's just a rule of thumb, not 100% always correct.

like image 33
Ralph Tandetzky Avatar answered Sep 17 '22 23:09

Ralph Tandetzky