tl; dr:是否可以将任意对象的生存期与另一个对象的生存期联系起来?
详细信息:我通常会处理here所述的问题,即我有一个std::vector<CppThing>
,但我必须使用的API的入口点的形式为{{ 1}}。我通常会采用与最高答案相同的方法,即让foo(const CThing**, int numThings)
是std::vector<CppThing>
的“所有者”,并使用CppThing
构造一个std::vector<CThing*>
方法。不幸的是,如果原始向量或其元素被修改,或者超出范围,则新向量中的指针将失效。也很难在函数调用边界上抽象此细节,例如CppThing::as_cthing()
。
是否可以将拥有容器的生存期与std::vector<CThing*> MakeThings() {...}
向量的生存期联系在一起,或者创建一个封装了两者的对象,但将其所有方法作为const转发给一个对象接口的方法? / p>
示例1:
CThing*
从语言的角度来看,我怀疑以上是不可能的,因为作用域生存期必须在编译时确定,如果将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
调用放在分支中会发生什么?
示例2:
Inject
基本上,我希望有一个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
派生出来似乎很容易解决,但是我读过的所有文章都说这样做很危险。