protobuf:RepeatedField独特的元素

时间:2013-04-08 13:16:30

标签: c++ c protocol-buffers

我想在谷歌协议缓冲区repeated field中只包含唯一元素。换句话说,需要将其用作std::set而不是std::vector

任何想法最简单,最有效的方法吗?

编辑:如果可能的话,我不想使用任何迭代器遍历所有元素。

2 个答案:

答案 0 :(得分:1)

好的,正如问题的评论所述,没有使用迭代器就没有办法做到这一点。 然而,也许其他人对此感兴趣,这里是我编写的功能来实现这一点。这将作为参数a RepeatedPtrField< T >*(列表)和std::string(我们打算添加到列表中的新对象的键),并将返回与id匹配的元素,或{{ 1}}如果NULL列表中没有此条目的任何条目。

这样,您可以直接在RepeatedField中轻松保留唯一元素列表,而无需使用任何其他RepeatedField结构:

std

注意:在上面的例子中,proto消息总是会有一个名为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; } 的字段(在我的例子中也是一个原型消息)。您可以将任何想要与原型消息进行比较的内容替换掉。

答案 1 :(得分:0)

在我有这个课程的情况下:

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);
    }
}