将 shared_ptr<StructA> 移动到 shared_ptr<variant<StructA, StructB>>

Emi*_*äck 5 c++ c++14 c++17

我试图避免为一组普通的旧数据结构使用相当复杂的继承链,但我需要将它们全部存储在一个向量中,并与调用者共享所有权。

Struct A {};
Struct B {};

using TInstruction = std::variant<A, B>;

struct holder {
  std::vector<std::shared_ptr<TInstruction>> items;
};

static holder h;

// Every individual TInstruction gets its own add function, for validation purposes
void add(std::shared_ptr<A> a) {
  // Somehow add this to h, while still sharing ownership with the caller
  // h.emplace_back(???)
}


int main() {
  holder h;

  auto a = std::make_unique<A>();
  auto b = std::make_unique<B>();

  add(a);
  // add(b) // not implemented
}
Run Code Online (Sandbox Code Playgroud)

通过对原始想法进行以下更改,我取得了中等(但非常糟糕)的成功:

  1. 在变体中使用共享指针,即 using TInstruction = std::variant<std::shared_ptr<A>, std::shared_ptr<B>>
  2. 接受 std::weak_ptradd()并用于.lock()将其转换为 std::shared_ptr

我不介意#2(在我看来这可能是正确的方法),但是将 shared_ptr 保留在它的“外部”内部的变体中会导致一些非常冗长的代码和模式匹配。

有可能做到这一点吗?我本质上想改变共享指针的类型,但仍然表达共享所有权的想法。

Emi*_*äck 0

根据评论,这是一个有点愚蠢的问题,因为变体必须是对象的所有者,最终类型才能是shared_pointer<variant>。Nevin 的建议可行,但使用了void类型,它有自己的问题(也许可以使用 any 类型?那不会更好。)

最后,我希望尽可能保持类型安全,并使所有权模型清晰,因此我将采用共享指针的变体。