Reputation: 2384
I got a structure and a function like the following:
struct MYOVERLAPPED : public OVERLAPPED
{
//...
};
void func1(std::unique_ptr<MYOVERLAPPED> pBuf)
{
//...
};
I am obtaining a pointer to MYOVERLAPPED which i want to pass to the func1-function. The problem i encounter is, that no matter what i try i get the following errors :
What i did try already are the following: Try1:
std::unique_ptr<OVERLAPPED> pOver(//....)
HandleAcceptIndication(std::move(pOver));
Error: Error 1 error C2440: 'initializing' : cannot convert from '_OVERLAPPED **' to 'MYOVERLAPPED *'
Try2:
HandleAcceptIndication(new ACCEPT_OVERLAPPED);
Error 1 error C2664: 'HandleAcceptIndication' : cannot convert parameter 1 from 'MYOVERLAPPED *' to 'std::unique_ptr<_Ty>'
Anyone knows how i can pass this casted pointer of OVERLAPPED to MYOVERLAPPED to the function and why Try2 does not work either since i casually use std::unique_ptr<MYOVERLAPPED> pO(new MYOVERLAPPED)
which does work...?
Upvotes: 1
Views: 6288
Reputation: 208323
While you cannot convert from std::unique_ptr<base>
to std::unique_ptr<derived>
directly, it is not too hard to write a cast function that will be safe (i.e. not leak the resource under any circumstance, and only succeed if the cast is valid:
template <typename Dst, typename Src>
std::unique_ptr<Dst> unique_dynamic_cast( std::unique_ptr<Src>& ptr ) {
Src * p = ptr.release(); // [1]
std::unique_ptr<Dst> r( dynamic_cast<Dst*>(p) ); // [2]
if ( !r ) {
ptr.reset( p ); // [3]
}
return r; // [4]
}
The basic idea is that we need to extract the pointer from the std::unique_ptr
and set it aside in [1]. We cannot try dynamic_cast
directly, as if that fails, ptr
would have released ownership, and the memory would be leaked. Then we try and perform the dynamic_cast
[2] from the local pointer to the requested type of pointer and pass ownership onto the r
result unique pointer. If the dynamic_cast
fails, then r
will be null, and we need to return ownership of the memory to the original std::unique_ptr
[3], for calling code to decide what to do with it. We then return the converted std::unique_ptr
to the caller in [4].
Upvotes: 11
Reputation: 75130
unique_ptr<A>
and unique_ptr<B>
are unrelated types. You can't convert between them unless an implicit conversion exists between A*
and B*
(thanks UncleBens), which is not true in this case. Also you should not cast down the inheritance hierarchy with an instance that is not the subclass you are casting to. In this case, you're trying to cast a OVERLAPPED
to a MYOVERLAPPED
which is an invalid cast because an OVERLAPPED
is not a MYOVERLAPPED
. That's why you can't convert between the unique_ptr
types in the first place.
If you are just trying to pass a unique_ptr
to func1
, you can do it like this:
func1(shared_ptr<MYOVERLAPPED>(new MYOVERLAPPED));
Also, by passing a unique_ptr
to a function, the pointer in the original one gets set to NULL. Consider using references or shared_ptr
s if you are not creating the unique_ptr
as a temporary and passing it to the function and you need to use the same instance later.
Upvotes: 0
Reputation: 146910
This doesn't work because you're trying to cast the wrong way in the inheritance hierarchy. You're trying to convert from Base* to Derived* implicitly.
Upvotes: 2