首页 > 解决方案 > 养育对象的生命周期

问题描述

tl;dr:有没有办法将任意对象的生命周期与另一个对象的生命周期联系起来?

详细信息:我通常处理此处描述的问题,即我有一个std::vector<CppThing>但我必须使用的 API 有一个形式的入口点foo(const CThing**, int numThings)。我通常采用与最佳答案相同的方法,即让sstd::vector<CppThing>成为 s 的“所有者” ,并使用该方法CppThing构造 a 。不幸的是,如果原始向量或其元素被修改,或者超出范围,新向量中的指针就会失效。在函数调用边界上抽象这个细节也很困难,例如.std::vector<CThing*>CppThing::as_cthing()std::vector<CThing*> MakeThings() {...}

有没有办法将拥有容器的生命周期与CThing*向量的生命周期联系起来,或者创建一个封装两者的对象,但将其所有方法作为 const 仅转发给一个对象接口?

示例 1:

std::vector<CThings*> MakeThings() {
  std::vector<CppThings> v = ...
  std::vector<CThings*> ret;
  for (const auto& x : v) ret.push_back(x.as_cthing());
  InjectLifetime(/*of*/ v, /*into*/ ret);
  return std::move(ret);
} // v goes out of scope but its destructor is not called until ret's is called

我怀疑从语言的角度来看上述是不可能的,因为范围生命周期必须在编译时确定,如果你把Inject调用放在分支中会发生什么?

示例 2:

SomeContainer<std::vector<CThings*>, std::vector<CppThings>> MakeThings() {
  std::vector<CppThing> v = ...
  std::vector<CThing*> cv;
  for (const auto& x : v) cv.push_back(x.as_cthing());
  SomeContainer<std::vector<CThings*>, std::vector<CppThings>> ret;
  ret.SetInterfaceObject(std::move(cv));
  ret.AddHolderObject(std::move(v));
  return ret;
}
...
auto cthings = MakeThings();
cthings.data(); // cv.data()
cthings.size(); // cv.size()
cthings.clear(); // compile error - method not const

基本上,我想要一个std::tuple将所有方法转发到特定元素的方法,并且只使用元组将对象绑定在一起。似乎这很容易通过派生来解决,std::vector但我读过的所有内容都表明这样做充满了危险。

标签: c++scopestllifetime

解决方案


推荐阅读