Reputation: 30675
I have code where I am trying to pass the underlying pointer of a unique_ptr in to a method accepting a pointer by reference:
unique_ptr<A> a;
func(a.get());
to call:
void func(A*& a){ // I am modifying what `a` points to in here
}
but I am getting compiler errors because get()
is not returning what I expected was just the raw pointer. Is it possible to achieve what I am trying to do here?
Upvotes: 3
Views: 1066
Reputation: 31
Here is an idea:
template<typename T> struct raw_from_ptr {
raw_from_ptr(T& pointer) : _pointer(pointer), _raw_pointer(null_ptr) {}
~raw_from_ptr() {
if (_raw_pointer != null_ptr)
_pointer.reset(_raw_pointer);
}
raw_from_ptr(pointer_wrapper&& _other) : _pointer(_other._pointer) {
std::swap(_raw_pointer, _other._raw_pointer);
}
operator typename T::pointer*() && { return &_raw_pointer; }
operator typename T::pointer&() && { return _raw_pointer; }
private:
T& _pointer;
typename T::pointer _raw_pointer;
};
template<typename T> raw_from_ptr<T> get_raw_from_ptr(T& _pointer) {
return raw_from_ptr<T>(_pointer);
}
Usage:
unique_ptr<A> a;
func(get_raw_from_ptr(a));
Upvotes: 3
Reputation: 48665
A function that takes a pointer by reference is strongly hinting that it may reallocate/delete the pointer in question. That means it is asking for ownership responsibilities. The only safe way to call such a function is to release the pointer from the unique pointer and (possibly) reacquire it after the call.
// a currently manages (owns) the pointer
std::unique_ptr<A> a;
// release ownership of internal raw pointer
auto raw = a.release();
// call function (possibly modifying raw)
func(raw);
// (re)claim ownership of whatever func() returns
a.reset(raw);
But that can still be problematic if (say) the unique_ptr
has a special deleter and the function doesn't re-allocate the object accordingly. Also if the function deletes the pointer without setting it to nullptr
you will have a problem.
Upvotes: 4
Reputation: 72215
No, and that's a good thing.
The problem is that get()
returns an rvalue, not a reference to unique_ptr
's internal pointer. Therefore you can't modify it. If you could, you would completely mess up unique_ptr
's internal state.
Just pass a reference to the unique_ptr
itself if you want to modify it.
Upvotes: 13