I love and often use C++ Rule of Zero, but now there’s a use case where I find it challenging to use.
I have 2 libraries, both maintained separately and even compiled with different compilers to different DLLs. One library consumes headers and calls functions of another library. Both are written in C++.
Now, let’s say that I need to add a function which receives const data such as an array of strings. In a normal C++ function I’d do:
struct Obj {
std::vector<std::string> strings;
};
void func(const Obj& obj);
But due to lack of C++ ABI guarantee, I can’t do that.
I thought about using std::unique_ptr
, but its ABI isn’t guaranteed either.
So I can do something like this:
class Obj {
public:
Obj(std::initializer_list<std::string_view> strings) {
// Allocate StringsWithAbi and copy strings
}
// Rule of Five goes here :(
private:
struct SymbolString {
char* string;
size_t length;
};
SymbolString* StringsWithAbi{};
};
void func(const std::vector<std::string> strings);
That requires to resort to Rule of Five and carefully implement copy/move constructors and the rest, which is error prone and just unpleasant boilerplate.
Is there anything simpler I can do? Note that I’d like to be able to use Obj
in C++ as well, at least with basic operations such as constructing, moving and copying. And I’d rather not create another copy of it only to call func
.
Is there any low-level utility like unique_ptr
which is has also stable ABI? Any better ideas?