Boost logo

Boost :

From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2023-12-04 21:00:39


On 12/4/23 22:38, Bruno Martínez via Boost wrote:
> Hi,
>
> unique_ptr can emulate unique_resource:
>
> template<auto nullvalue, auto delete_>
> class unique
> {
> using T = decltype(nullvalue);
>
> struct generic_delete
> {
> class pointer
> {
> T t;
> public:
> pointer(T t) : t(t) {}
> pointer(std::nullptr_t = nullptr) : t(nullvalue) { }
> explicit operator bool() { return t != nullvalue; }
> friend bool operator ==(pointer lhs, pointer rhs) {
> return lhs.t == rhs.t; }
> friend bool operator !=(pointer lhs, pointer rhs) {
> return lhs.t != rhs.t; }
> operator T() { return t; }
> };
>
> void operator()(T p)
> {
> delete_(p);
> }
> };
> public:
> using type = std::unique_ptr<struct not_used, generic_delete>;
> };
>
> int main()
> {
> using unique_fd = unique<-1, close>::type;
> static_assert(sizeof(unique_fd) == sizeof(int), "bloated unique_fd");
> unique_fd fd1(open("fd.txt", O_WRONLY | O_CREAT | O_TRUNC));
> write(fd1.get(), "hello\n", 6);
> }
>
> The std papers say
>
> While std::unique_ptr can be tweaked by using a custom deleter
> type to almost a
> perfect handler for resources, it is awkward to use for handle types
> that are not pointers.
>
> But what's the awkwardness?

You are hijacking a tool that was not intended to be used this way.
unique_ptr is only supposed to be used with pointers and pointer-like
objects, which is why it accepts nullptr in its interface. The syntax:

  fd1 = nullptr;

is allowed, but it doesn't make sense for the reader who expects fd1 to
be a file descriptor. This would be especially confusing if the resource
type was a pointer type, with the unallocated value being something else
than a null pointer. Case in point, Windows' HANDLE and
INVALID_HANDLE_VALUE.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk