我想在google协议缓冲区repeated field
中有唯一的元素。换句话说,需要使用它作为std::set
而不是std::vector
。protobuf:RepeatedField独特元素
任何想法,这是最简单和最有效的方式来做到这一点?
编辑:我不想使用任何迭代器遍历所有元素,如果可能的话。
我想在google协议缓冲区repeated field
中有唯一的元素。换句话说,需要使用它作为std::set
而不是std::vector
。protobuf:RepeatedField独特元素
任何想法,这是最简单和最有效的方式来做到这一点?
编辑:我不想使用任何迭代器遍历所有元素,如果可能的话。
好的,从问题的评论中可以看出,没有任何方法可以在不使用迭代器的情况下做到这一点。 但是,也许有人对此感兴趣,下面是我编写的功能来实现这一点。这将作为参数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);
}
}
谷歌protobufs不支持细节在他们的界面细节。你可以修改源代码,但这似乎是一个巨大的浪费时间。遍历所有元素并将它们添加到集合可能是最好的解决方案。 – Josh 2013-04-08 14:26:34
... k,thnks,证实了我的发现:) – Alex 2013-04-08 15:14:20
你是否被google protobufs约束了,或者你被允许为你的代码使用不同的工具包? – Josh 2013-04-08 15:49:14