Why does unique_ptr overload reset (pointer p = pointer ()) and reset (nullptr_t)?

Verification http://en.cppreference.com/w/cpp/memory/unique_ptr/reset ,

void reset( pointer ptr = pointer() ); template< class U > void reset( U ) = delete; void reset( std::nullptr_t p ); 

1) When current_ptr specified, a pointer controlled by *this performs the following actions in the following order: Saves a copy of the current pointer old_ptr = current_ptr ; Overwrites the current pointer with the argument current_ptr = ptr ; If the old pointer was not empty, removes the previously managed if(old_ptr != nullptr) get_deleter()(old_ptr) .

2) In the specialization for dynamic arrays std::unique_ptr<T[]> , this template element is provided to prevent the use of reset() with a pointer to a derivative (which will lead to undefined behavior with arrays).

3) In the specialization for dynamic arrays std::unique_ptr<T[]> , a third overload is needed to enable reset nullptr (which otherwise overloads the template). Equivalent to reset(pointer())

Now that reset(nullptr) equivalent to reset(pointer()) , why do the latter exist?

If I want to reset to create a unique_ptr array, why can't I just use rest(pointer()) ?

+3
source share
2 answers

 template< class U > void reset( U ) = delete; 

will be selected for invocation with argument nullptr , if not for

 void reset( std::nullptr_t p ); 

That's why it exists to allow a call using nullptr .


Example (compile with FIX defined to suppress a compilation error):

 #include <cstddef> // std::nullptr_t struct S { void reset( char* ) {} template< class Type > void reset( Type ) = delete; #if FIX void reset( std::nullptr_t ) {} #endif }; auto main() -> int { S().reset( nullptr ); // Fails when FIX is not defined. } 
+7
source

reset ist implemented as

 pointer old = this->ptr; this->ptr= newPointer; delete[] old; 

Template overload is removed for arrays to prevent the following case

 class foo{}; class bar : public foo {}; foo* managedPointer = new foo[3]; bar* newPointer = new bar[5]; foo* old = managedPointer; managedPointer = newPointer; delete[] old; 

What behavior is undefined. Section 5.3.5, paragraph 3:

[...] In the second alternative (delete array), if the dynamic type of the object to be deleted is different from its static type, the behavior is undefined.

Since remote functions are still involved in overload resolution and reset(U) provides a better match for nullptr than reset(pointer) , there is an additional overload to enable reset(nullptr) , which otherwise would give a compiler error and thus , would lead to an inconsistent interface between the array and the version of the pointer.

+2
source

Source: https://habr.com/ru/post/974346/


All Articles