2013-04-08 707 views
0

我想在google协议缓冲区repeated field中有唯一的元素。换句话说,需要使用它作为std::set而不是std::vectorprotobuf:RepeatedField独特元素

任何想法,这是最简单和最有效的方式来做到这一点?

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

+1

谷歌protobufs不支持细节在他们的界面细节。你可以修改源代码,但这似乎是一个巨大的浪费时间。遍历所有元素并将它们添加到集合可能是最好的解决方案。 – Josh 2013-04-08 14:26:34

+0

... k,thnks,证实了我的发现:) – Alex 2013-04-08 15:14:20

+0

你是否被google protobufs约束了,或者你被允许为你的代码使用不同的工具包? – Josh 2013-04-08 15:49:14

回答

1

好的,从问题的评论中可以看出,没有任何方法可以在不使用迭代器的情况下做到这一点。 但是,也许有人对此感兴趣,下面是我编写的功能来实现这一点。这将作为参数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(在我的情况下也是原始消息)。您可以用您想要与原始消息进行比较的任何东西来替换它。

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