Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

weak_ptr's weird copy constructors

the following are 2 of weak_ptr's constructors: http://msdn.microsoft.com/en-us/library/bb982126.aspx

weak_ptr(const weak_ptr&);

template<class Other>
weak_ptr(const weak_ptr<Other>&);

actual code (from memory):

weak_ptr(const weak_ptr& _Other)
{   // construct weak_ptr object for resource pointed to by _Other
    this->_Resetw(_Other);
}

template<class _Ty2>
weak_ptr(const weak_ptr<_Ty2>& _Other,
         typename enable_if<is_convertible<_Ty2 *, _Ty *>::value,
         void *>::type * = 0)
{   // construct weak_ptr object for resource pointed to by _Other
    this->_Resetw(_Other);
}

Q1: Why is the top copy constructor even there? It looks like the bottom one accounts for every case (including the top one). Does it even get called? and if they didn't include it would the bottom one take it's place?

Q2: What's going on with the second argument of the bottom (templated) constructor. I think I understand the SFINAE aspect, but I don't understand why there is an extra * after ::type

like image 755
David Avatar asked Jan 19 '23 23:01

David


2 Answers

Q1) If you don't write a copy constructor, the compiler will generate one for you, which wouldn't be what you want. Templated conversion constructors don't count.

Q2) Remember that shared_ptr<T> is like a T*, convertibility must be checked at the level of pointers. If T* is convertible to U* then you should be able to assign one to the other. Think of pointers-to-base. [Sorry, that wasn't what you asked.] The final argument type just needs to exist, but also we don't want to have to specify the argument itself. A universal way of making up a type for which we can also provide a default argument is a pointer. In short, we need to make the function depend on a type that may or may not exist, but without actually requiring the user to know about this.

like image 195
Kerrek SB Avatar answered Jan 31 '23 10:01

Kerrek SB


Re Q1: a templated constructor is never a "copy constructor", even if it manages to copy. if there is no user-defined "copy constructor", then the compiler will generate one as needed.

Re Q2: the second argument, a pointer defaulted to 0, is just to have a place to put the enable_if. you can find more about that (if i recall correctly) in the Boost documentation.

Cheers & hth.,

like image 32
Cheers and hth. - Alf Avatar answered Jan 31 '23 09:01

Cheers and hth. - Alf