![](/img/trans.png)
[英]What is the most efficient way to get all elements from a ProtoBuf RepeatedField?
[英]protobuf: RepeatedField unique elements
我想在Google协议缓冲区中repeated field
仅包含唯一元素。 换句话说,需要将其用作std::set
而不是std::vector
。
有什么想法是最简单,最有效的方法吗?
编辑 :如果可能的话,我不想使用任何迭代器来遍历所有元素。
好的,正如问题的评论所述,不使用迭代器是没有任何办法的。 但是,也许其他人对此感兴趣,这是我编写的实现此功能的函数。 这将使用RepeatedPtrField< T >*
(列表)和std::string
(我们打算添加到列表中的新对象的键)作为参数,并将返回与id匹配的元素;如果存在,则返回NULL
在RepeatedField
列表中没有任何使用此键的条目。
这样,您可以轻松地将唯一元素的列表直接保留在RepeatedField
而无需使用任何其他std
结构:
template <class T>
T* repeatedFieldLookup( google::protobuf::RepeatedPtrField< T >* repeatedPtrField, std::string id)
{
google::protobuf::internal::RepeatedPtrOverPtrsIterator<T> it = repeatedPtrField->pointer_begin();
for ( ; it != repeatedPtrField->pointer_end() ; ++it )
{
CommonFields * commonMessage = (CommonFields*) (*it)->GetReflection()->
MutableMessage ((*it), (*it)->GetDescriptor()->FindFieldByName ("common"));
if(commonMessage->id() == id)
{
return *it;
}
}
return NULL;
}
注意 :在上面的示例中,原始消息将始终具有一个称为common
的字段(在我的情况下,这也是原始消息)。 您可以将其替换为要与原始消息进行比较的任何内容。
在我上这节课的情况下:
class Description : public ::google::protobuf::Message {
// ...
inline void add_field(const ::std::string& value);
inline const ::google::protobuf::RepeatedPtrField< ::std::string>& field() const;
// ...
};
我使用std::find
仅在列表中不存在的情况下添加一个值:
#include <algorithm>
void addField(Description& description, const std::string& value) {
const auto& fields = description.field();
if (std::find(fields.begin(), fields.end(), value) == fields.end()) {
description.add_field(value);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.