使用 C++11+ 的 Libevent unique_ptr
Libevent with C++11+ unique_ptr
我最近尝试用 std::unique_ptr
和自定义删除器包装 libdbus
类型和 libevent
类型以简化代码,但这些库出现错误:
/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,
^
代码很简单:
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>;
// ...
}
};
那么如何在这个例子中为 event_base
结构编写 RAII 包装器?
P.S。我发现 event_base
结构是在 event2/event.h
中向前声明的。所以没有包装它的选项?
由于 std::unique_ptr
没有 type-erase 它的删除器,并且 the default deleter 不适用于不完整的类型,您需要提供一个替代删除器作为类型签名的一部分:
struct EventBaseDeleter {
void operator()(event_base* ptr) const {
sockets::libev::event_base_free(ptr);
}
};
using UniqueEventBase = std::unique_ptr<event_base, EventBaseDeleter>;
header event2/event.h
故意不定义 event_base
以便实现是私有的。
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.
因此,您需要通过提供自己的删除器作为模板的第二个参数来避免使用默认删除器。
这在这种情况下尤其有意义,您希望调用 event_base_free
而不是尝试 delete
它。
我最近尝试用 std::unique_ptr
和自定义删除器包装 libdbus
类型和 libevent
类型以简化代码,但这些库出现错误:
/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,
^
代码很简单:
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>;
// ...
}
};
那么如何在这个例子中为 event_base
结构编写 RAII 包装器?
P.S。我发现 event_base
结构是在 event2/event.h
中向前声明的。所以没有包装它的选项?
由于 std::unique_ptr
没有 type-erase 它的删除器,并且 the default deleter 不适用于不完整的类型,您需要提供一个替代删除器作为类型签名的一部分:
struct EventBaseDeleter {
void operator()(event_base* ptr) const {
sockets::libev::event_base_free(ptr);
}
};
using UniqueEventBase = std::unique_ptr<event_base, EventBaseDeleter>;
header event2/event.h
故意不定义 event_base
以便实现是私有的。
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.
因此,您需要通过提供自己的删除器作为模板的第二个参数来避免使用默认删除器。
这在这种情况下尤其有意义,您希望调用 event_base_free
而不是尝试 delete
它。