2013-04-08 109 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); 
    } 
}