4

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

有什么想法是最简单和最有效的方法吗?

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

4

2 回答 2

2

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

这样,您可以轻松地将唯一元素列表直接保存在 a 中,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(在我的例子中也是一个原始消息)。您可以将其替换为您想从原始消息中进行比较的任何内容。

于 2013-04-11T09:43:25.983 回答
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);
    }
}
于 2015-04-16T15:59:27.113 回答