简体   繁体   中英

A (different) helper for `std::unique_ptr`

I see that there is only one non-member utility helper associated with std::unique_ptr , and it invokes new . What about a utility for wrapping an existing raw pointer without having to explicitly name the type?

In particular, suppose there is legacy code or external library that has something like this:

C* foo();  // caller is responsible for deleting

That is, some function that ought to be written as returning a unique_ptr<C> , but isn't, and the caller is not in a position to change it.

I think the proper way to use this function is with:

unique_ptr<C> up (foo());

but that requires naming the type, rather than using auto . It begs the question as to why there's not a helper function that would use template argument deduction and write something like:

auto up= capture_unique(foo());

Ideally, even provide for the = syntax in declaring the variable, as well as figuring out the type by itself.

It's such a natural way to write it that I can't imagine that I'm the first to think of it. Is there some hidden peril that makes it impossible to write this in a general enough case? Or, what reason is it not provided along with make_unique and the unique_ptr template as part of the standard?

The simplest code that satisfies the requirement you describe would be;

template<typename T>
auto capture_unique(T* ptr)
{
  return std::unique_ptr<T>{ptr};
}

And that would work nicely with the sample code;

auto up = capture_unique(foo());

There is essentially little difference between the capture_unique and just using the unique_ptr constructor directly, other than as you say, retyping the type C .

auto up = std::unique_ptr<C>{foo()};

For generic code you could look to use decltype and declval etc. A generalised use case probably does not exist.

In the same problem exists for std::shared_ptr where there is again no "capture" type helper method, again, creating one is simple enough. The difference between the shared_ptr case and the unique_ptr is that the deleter is part of the type with unique_ptr and not with shared_ptr .

Is there some hidden peril that makes it impossible to write this in a general enough case?

No hidden peril, just some unanswered general questions on what types to use. But easy enough to create, as above.

Or, what reason is it not provided along with make_unique and the unique_ptr template as part of the standard?

It is possible that the deleter being part of the type is a good reason to not create a utility capture method (and thus in turn it is not mirrored for shared_ptr ). The capture_unique would not be able to provide a better syntax if the deleter was the default delete - it may well be more cumbersome.

Note: both the "factory" methods, make_unique and make_shared use the new operator and marry that with the default delete deleter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM