0

I've recently tried to wrap libdbus types and libevent types with std::unique_ptr and custom deleter to simplify the code but I have a error with these libraries:

/opt/cross/armv7hl-meego-linux-gnueabi/include/c++/4.8.3/bits/unique_ptr.h:65:22: error: invalid application of 'sizeof' to incomplete type 'sockets::libev::event_base'
  static_assert(sizeof(_Tp)>0,
                      ^

The code is simple:

namespace sockets {
    // ... unix sockets stuff
    namespace libev {
        #include <event.h>
    } // libev
} // sockets

class A {
public:
    void run() {
        using namespace sockets;
        using namespace sockets::libev;
        using UniqueEventBase = std::unique_ptr<event_base>;
        // ...
    }   
};

So how do I write RAII-wrappers for event_base struct in this example ?

P.S. I have found that event_base struct is forward declared in event2/event.h. So there is no option to wrap it?

VP.
  • 15,509
  • 17
  • 91
  • 161

2 Answers2

3

Since std::unique_ptr does not type-erase its deleter, and the default deleter does not work on incomplete types, you need to provide an alternative deleter as part of the type signature:

struct EventBaseDeleter {
  void operator()(event_base* ptr) const {
    sockets::libev::event_base_free(ptr);
  }
};

using UniqueEventBase = std::unique_ptr<event_base, EventBaseDeleter>;
You
  • 22,800
  • 3
  • 51
  • 64
2

The header event2/event.h deliberately does not define event_base so that the implementation is kept private.

CPP Reference Says:

std::unique_ptr may be constructed for an incomplete type T, such as to facilitate the use as a handle in the pImpl idiom. If the default deleter is used, T must be complete at the point in code where the deleter is invoked, which happens in the destructor, move assignment operator, and reset member function of std::unique_ptr.

So, you need to avoid using the default deleter by providing your own, as the second argument to the template.

This make sense especially in this case, where you would want to call event_base_free rather than trying to delete it.

harmic
  • 28,606
  • 5
  • 67
  • 91