具有保证/C ABI 的 C++ 零规则

问题描述 投票:0回答:1

我喜欢并且经常使用 C++ 零规则,但现在有一个用例,我发现它很难使用。

我有 2 个库,都是单独维护的,甚至用不同的编译器编译成不同的 DLL。一个库使用标头并调用另一库的函数。两者都是用 C++ 编写的。

现在,假设我需要添加一个接收常量数据(例如字符串数组)的函数。在普通的 C++ 函数中我会这样做:

struct Obj {
    std::vector<std::string> strings;
};

void func(const Obj& obj);

但由于缺乏 C++ ABI 保证,我不能这样做。

我考虑过使用

std::unique_ptr
,但是 它的 ABI 也无法保证

所以我可以做这样的事情:

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);

这需要诉诸五法则并仔细实现复制/移动构造函数和其余的,这很容易出错并且只是令人不快的样板。

我能做一些更简单的事情吗?请注意,我希望也能够在 C++ 中使用

Obj
,至少能够在构造、移动和复制等基本操作中使用。我不想创建它的另一个副本只是为了调用
func

是否有像

unique_ptr
这样具有稳定 ABI 的低级实用程序?还有更好的想法吗?

c++ stl abi
1个回答
0
投票

我不知道这是否是作弊,但是......为什么不使用实用程序类并在适当的情况下重用它呢?据我所知,否则你所要求的就是不可能的。

(未测试)


template <class T>
class HeapObject;

template<> class HeapObject<void> {
  HeapObject(void * storage) : storage_(storage) {}

  HeapObject(HeapObject && rhs) : storage_(rhs.storage_) {
     rhs.storage_ = nullptr;
  }

  HeapObject & operator=(HeapObject && rhs) {
      storage_ = rhs.storage_;
      rhs.storage_ = nullptr;
      return *this;
  }
  HeapObject & operator=(HeapObject const &) = delete;

protected:
   void * storage_;
};

template <class T>
struct HeapObject : HeapObject<void> {
public:
   T * operator->() {
      return reinterpret_cast<T*>(storage_);
   }

   T const * operator->() const {
      return reinterpret_cast<T*>(storage_);
   }

   T const * operator*() const {
      return reinterpret_cast<T const *>(storage_);
   }

   T * operator*() const {
      return reinterpret_cast<T const *>(storage_);
   }

   ~HeapObject() {
       delete reinterpret_cast<T*>(storage_);
   }
};


struct Obj {
    // This or pimpl
    HeapObject<std::vector<std::string>> vec_{new std::vector<std::string>{}};
};

void func(const Obj& obj);
© www.soinside.com 2019 - 2024. All rights reserved.