Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 398
Egor Tensin Avatar asked Oct 20 '22 13:10

Egor Tensin


2 Answers

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.

like image 139
Steger Avatar answered Oct 23 '22 03:10

Steger


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.

like image 29
Angew is no longer proud of SO Avatar answered Oct 23 '22 02:10

Angew is no longer proud of SO