2017-02-06 3 views
0

Ich habe Refactoring alten Code zu ersetzen, der wie folgt aussieht (Ich bin nicht sehr bewandert C++ Coder)Der beste Weg, einen Satz in C++

std::set<SomeObject>::iterator it = setobject.begin(); 

do { 
    it->setProperty1ToNextValue(); 
    it->getProperty2(); 
    it->getProperty3(); 
    it++ 
} while (it != setobject.end()); 

Grundsätzlich ich durch die Elemente des Satzes iterieren wollen und Holen und setzen/aktualisieren Sie einige ihrer Eigenschaften. Ich kann nicht den ursprünglichen Satz verwenden, da ich in den Problemen in diesem Thread the object has type qualifiers that are not compatible with the member function object type is const

beschrieben laufen

I des Ersetzens des Satzes mit einem dequeue denke (es wird einige Umschreiben beinhalten), da ich dann in der Lage sein zu setzen und erhalten Eigenschaften für jedes Element der Warteschlange. Ist das ein guter Ansatz?

+0

Wenn die 'std :: set'-Richtlinien nicht mehr gelten, was brauchen Sie eigentlich? Eine 'std :: unordered_map' vielleicht? Übrigens scheinen alle Ihre Funktionsaufrufe in der Probe NOPs zu sein, außer es gibt irgendwelche Nebenwirkungen. Erwäge das Posten von _real code_. –

+1

Warum denkst du, dass du Set nicht benutzen kannst? – koalo

+2

Sie können die Schlüsseleigenschaften eines Satzes nicht ändern, aber Sie können das Element mit den alten Eigenschaften entfernen und durch ein neues ersetzen. Wenn Sie jedoch ein Set durchlaufen, haben Sie wahrscheinlich die falsche Datenstruktur. –

Antwort

3

Ein std::set funktioniert, indem alle Artikel gemäß dem Objekt < des Objekts in Reihenfolge gehalten werden. Der Grund, warum Sie nicht-konstante Methoden für Ihr Objekt aufrufen können, ist, weil das Risiko besteht, dass diese Methoden den von Ihrem Objekt zurückgegebenen Wert ändern und somit das Set effektiv unter der Haube "neu ordnen", ohne das std::set Wissen.

Während Sie nicht genug angegeben haben, was Sie für uns tun möchten, um die beste Antwort zu geben, hier ist ein paar Möglichkeiten, um technisch einige Methoden auf Ihrem Gerät aufrufen zu erreichen. Sie können const_cast verwenden, um Methoden aufzurufen, von denen Sie sicher sind, dass sie den Schlüssel nicht ändern. Oder Sie können die Elemente in einen Vektor einfügen, Methoden aufrufen, die den "Schlüssel" ändern, und sie dann wieder in den ursprünglichen Satz einfügen.

// Example program 
#include <iostream> 
#include <string> 
#include <set> 
#include <algorithm> 

class SomeObject 
{ 
    std::string key; 
    int   data; 

public: 
    SomeObject(const std::string& key_, int data_) : key(key_), data(data_) 
    {} 

    // For a item to be in a set, it must have a "<" operator that tells it how to order it 
    bool operator <(const SomeObject& rhs) const 
    { 
     return key < rhs.key; 
    } 

    void setKey(const std::string& key_) 
    { 
     key = key_; 
    } 

    void setData(int data_) 
    { 
     data = data_; 
    } 
}; 

int main() 
{ 
    std::set<SomeObject> setobject; 
    setobject.insert(SomeObject("c", 1)); 
    setobject.insert(SomeObject("a", 1)); 
    setobject.insert(SomeObject("b", 1)); 

    // internally, the set will keep everything in order "a", "b", "c" 

    // option 1 - use const_cast (risky!) 
    { 
     std::set<SomeObject>::iterator it = setobject.begin(); 

     do { 
      // const_cast< SomeObject& >(*it).setKey("d"); bad idea, now the set is jacked up because its not in the right order 
      const_cast< SomeObject& >(*it).setData(2); 
      it++; 
     } while (it != setobject.end()); 
    } 

    // option 2 - put the items in the vector, call the methods, then put them back in the original set 
    { 
     std::vector<SomeObject> tempVec(std::begin(setobject), std::end(setobject)); 
     std::vector<SomeObject>::iterator it = tempVec.begin(); 
     do { 
      it->setKey("d"); 
      it->setData(2); 
      it++; 
     } while (it != tempVec.end()); 

     std::set<SomeObject> newSet(std::begin(tempVec), std::end(tempVec)); 
     std::swap(newSet, setobject); // put the new items back in the original setobject 
    } 



} 
Verwandte Themen