Smart pointer deleter and "use" of a keyword named "pointer"

Sometimes I saw this code:

void* Create() { int* t{new int{10}}; return t; } class Deleter { //uncomment in order to compile //using pointer = void*; public: void operator()(void* t) { delete t; } }; unique_ptr<int, Deleter> ptr{Create()}; 

It does not compile. From VS2013, he says:

error: C2440: 'initializing': cannot convert from 'initializer-list' to 'std :: unique_ptr' Constructor cannot use source type or overload constructor was ambiguous

But if I uncomment the line using pointer = void*; , she works! Also, if I change the alias name to something other than pointer , I get the same error. It seems that having a using directive with the exact name pointer is crucial. But why? I could not find any explanation.

+7
c ++ smart-pointers
source share
2 answers

Your unique_ptr declared using T=int . However, the constructors in std::unique_ptr accept instead of T* , but a pointer argument.

This type of pointer , defined as

 std::remove_reference<Deleter>::type::pointer if that type exists, otherwise T* 

And when you do not provide Deleter::pointer , it ends as int* and, of course, cannot be initialized from void* (from Create ).

+6
source share

[C++11: 20.7.1.2/3] If the type remove_reference<D>::type::pointer exists, then unique_ptr<T, D>::pointer must be synonymous with remove_reference<D>::type::pointer . Otherwise, unique_ptr<T, D>::pointer must be synonymous with T* . The type unique_ptr<T, D>::pointer must satisfy the requirements of NullablePointer (17.6.3.3).

It is required here because you do not have operator()(int*) - you are β€œhacking” around this, so instead of using operator()(void*) use instead deleter to do this deleter for void* .

Whether your deleted is generally unchanged even when it compiles, I would not want to say.

+1
source share

All Articles