gpt4 book ai didi

c++ - 用非基元填充 CapnProto 列表

转载 作者:行者123 更新时间:2023-11-30 05:03:29 28 4
gpt4 key购买 nike

根据 CapnProto 文档:(注意:我使用的是 C++ 版本)

For List where Foo is a non-primitive type, the type returned by operator[] and iterator::operator*() is Foo::Reader (for List::Reader) or Foo::Builder (for List::Builder). The builder’s set method takes a Foo::Reader as its second parameter.

虽然使用“set”似乎对非原始类型工作得很好: Other stack overflow question for primitives only

对于自动生成的非基元列表,似乎没有“设置”功能。我的 CapnProto 生成是否以某种方式失败了,或者是否有另一种方法可以在非基元列表中设置元素?

最佳答案

有一个“set”方法,但它叫做setWithCaveats():

destListBuilder.setWithCaveats(index, sourceStructReader)

这是为了让您知道在设置结构列表的元素时存在一些难以理解的问题。问题源于这样一个事实,即结构列表不是如您预期的那样表示为指针列表,而是它们是一系列“扁平化”的连续结构,大小都相同。这意味着在您初始化列表时为列表中的所有结构分配空间。因此,当您调用 setWithCaveats() 时,目标空间之前已分配,您正在将源结构复制到该空间。

这在面对不同版本时提出了一个问题:源结构可能是使用较新版本的协议(protocol)构建的,其中定义了额外的字段。在这种情况下,它实际上可能比预期的要大。但是,根据您编译时使用的协议(protocol)版本,目标空间已经分配。所以,它太小了!不幸的是,我们别无选择,只能丢弃我们不知道的新定义字段。因此,数据可能会丢失。

当然,可能是在您的应用程序中,您知道结构值不是来自较新版本,或者您不关心是否丢失了您不知道的字段。在这种情况下,setWithCaveats() 将执行您想要的操作。

如果您想小心保留未知字段,您可能需要查看方法 capnp::Orphanage::newOrphanConcat()。此方法可以以不丢失任何数据的方式将结构读取器列表的列表连接成单个列表——目标列表分配的每个结构的大小等于所有输入结构的最大值。

auto orphanage = Orphanage::getForMessageContaining(builder);
auto orphan = orphanage.newOrphanConcat({list1Reader, list2Reader});
builder.adoptListField(kj::mv(orphan));

关于c++ - 用非基元填充 CapnProto 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49373700/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com