I\'m using Word-Net, an old C library developed by Princeton University back in the nineties. The library is written in C, and only reveals the headers but not its actual implem
You can use std::shared_ptr
for this purpose, as you can provide the deleter to use to free the pointer.
std::shared_ptr<Synset> findTheInfo(...) {
std::shared_ptr<Synset> sp(findtheinfo(...), free_syns);
return sp;
}
std::shared_ptr<Synset> tracePtrs(...) {
std::shared_ptr<Synset> sp(traceptrs(...), free_synset);
return sp;
}
Now, if they really represent different things, you might want to spend a bit more effort and provide two types that wrap each use and provide the appropriate interface. Does it make sense to treat both as the same type when transversing a list and a tree might be completely different?
I know how to solve this problem for unique ownership, using unique_ptr
's nifty feature where its managed type becomes Deleter::pointer
, instead of T*
, if the former type exists.
Assuming you don't have the definition of Synset
, or whatever type SynsetPtr
points to, the problem with using a shared_ptr
is that it doesn't have the same facility of switching the managed type, and if you create a shared_ptr<SynsetPtr>
, the constructor will expect a SynsetPtr*
, but your C API functions don't return that type. And I don't know for sure whether using shared_ptr<remove_pointer<SynsetPtr>::type>
will compile if you don't have the definition of the type that dereferencing a SynsetPtr
yields.
This might work, but I'm not sure.
std::shared_ptr<std::remove_pointer<SynsetPtr>::type>
make_findtheinfo_ds(char *searchstr, int pos, int ptr_type, int sense_num)
{
return std::shared_ptr<std::remove_pointer<SynsetPtr>::type>
(findtheinfo_ds(searchstr, pos, ptr_type, sense_num),
free_syns);
}
std::shared_ptr<std::remove_pointer<SynsetPtr>::type>
make_traceptrs_ds(SynsetPtr synptr, int ptr_type, int pos, int depth)
{
return std::shared_ptr<std::remove_pointer<SynsetPtr>::type>
(traceptrs_ds(synptr, ptr_type, pos, depth),
free_synset);
}
Going the unique ownership route, I'd make a couple of factory functions that return unique_ptr
s managing SynsetPtr
s.
We need 2 separate deleters for the different kinds of SynsetPtr
s
struct sense_list_del
{
using pointer = SynsetPtr;
void operator()(SynsetPtr p)
{
free_syns(p);
}
};
struct linked_list_del
{
using pointer = SynsetPtr;
void operator()(SynsetPtr p)
{
free_synset(p);
}
};
std::unique_ptr<SynsetPtr, sense_list_del>
make_findtheinfo_ds(char *searchstr, int pos, int ptr_type, int sense_num)
{
return std::unique_ptr<SynsetPtr, sense_list_del>
(findtheinfo_ds(searchstr, pos, ptr_type, sense_num));
}
std::unique_ptr<SynsetPtr, linked_list_del>
make_traceptrs_ds(SynsetPtr synptr, int ptr_type, int pos, int depth)
{
return std::unique_ptr<SynsetPtr, linked_list_del>
(traceptrs_ds(synptr, ptr_type, pos, depth));
}