Egor Tensin
Egor Tensin

Reputation: 608

How do I use std::unique_ptr<T> with an interface that returns an int?

I want to wrap the open/close POSIX API into a RAII-compatible object like std::unique_ptr. But the open function returns an int (i.e. not a HANDLE, which is a pointer to void), and I'm not sure how I can use the std::unique_ptr template class with an int. Can somebody please help me?

Upvotes: 5

Views: 1079

Answers (2)

Steger
Steger

Reputation: 906

Really, all you want is for the close(int fileHandle) to be managed for you, right? Why not create a simple c++ class with a destructor that calls close() for you? I think this is the behavior you are looking for.

std::shared_ptr, and friends only deal with heap pointers created with new, and will call delete ptr, not what you are looking for here.

Edit: Mr. Fernandes makes a good point. shared_ptr<> manages reference counting for you, so using it with a custom deleter for an opaque handle from a c lib call (e.g. file handle) is a very reasonable thing to do, if just a tad tricky for other team members to follow. It also directly answer's OP's question.

Here's an interesting discussion on the topic from Herb Sutter's web site.

Upvotes: 2

It's not guaranteed to work by the standard (the result is implementation-defined), but I'd guess that on most sane implementations, doing a round trip int -> void* -> int will give you the same int value. So you could do this:

std::shared_ptr<void> raii(
  reinterpret_cast<void*>(open(/*...*/),
  [](void *p) { close(reinterpret_cast<int>(p)); }
);

This uses a custom deleter which calls close(). You might want to wrap this in your own class to present a nicer outside interface while still leveraging std::shared_ptr's implementation with regards to sharing & thread safety.

Upvotes: 1

Related Questions