2010-11-18 10 views
1

Ich habe mehrere Standardmengen von Ganzzahlen, auf die ich von mehreren Übersetzungseinheiten zugreifen kann. Das Ziel besteht darin, diese Standardsätze in Abhängigkeit vom Kontext des Codes in lokale Mengen zu setzen.Sätze, die aus einer Kombination von Elementen und anderen Mengen bestehen, die zum Erstellen von Mengen in C++ verwendet werden.

Zum Beispiel ist die beste Lösung, die ich habe ist:

#include <boost/assign/list_of.hpp> 
#include <set> 

const std::set<int> set9 = 
    boost::assign::list_of(4)(10)(108); 

const std::set<int> set10 = 
    boost::assign::list_of(3)(5)(10)(108); 

const std::set<int> set11 = 
    boost::assign::list_of(2)(3)(5)(101); 

int main(void) 
{ 
    std::set<int> my_set(set9); 
    my_set.insert(set11.begin(), set11.end()); 

    return 0; 
} 

Sie brauchen nicht konstant Globals zu sein, in der Tat, ich wahrscheinlich Funktionen bevorzugen, aber wenn sie Funktionen sind dann hätte ich zu Fügen Sie jedes Mal eine zusätzliche Zeile und eine extra gesetzte Variable hinzu, wenn ich mehr als eine Variable verwenden möchte.

Es würde wie folgt aussehen (mit einem weiteren Standard-Set als vorher):

std::set<int> my_set(get_set9()); 
    std::set<int> extra_line(get_set11()); 
    my_set.insert(extra_line.begin(), extra_line.end()); 
    std::set<int> another_extra_line(get_set12()); 
    my_set.insert(another_extra_line.begin(), another_extra_line.end()); 

Es sei denn, ich bin etwas fehlt?

Der Grund, warum ich Funktionen bevorzugen würde, ist, dass es zusätzliche Komplexität gibt. Unter den konstanten Mengen gibt es wiederholte Werte mit zusammenhängenden Bedeutungen, so dass ich sie nicht jedes Mal wiederholen möchte, wenn sich eine Änderung ergibt (und eine Code-Duplizierung verhindern).

In meinem vorherigen Beispiel sagen, dass 10 und 108 verbunden sind und immer zusammen erscheinen sollten. Wenn dies Funktionen wären, könnte ich einfach get_set11() und get_set12() eine gemeinsame Funktion aufrufen (wie get_set2(), die nur 10 und 108 hat). Mit dem Konstantensatz-Ansatz bin ich jedoch nicht sicher, wie diese Konstantensätze aufgebaut werden, die andere Mengen enthalten. Das Beste, was ich habe, ist:

Was funktioniert, aber ich würde es vorziehen, den Pre-Prozessor-Makro zu vermeiden.

nicht kompiliert Dies nicht, aber ich möchte in der Lage sein, so etwas zu tun:

const std::set<int> set2 = 
    boost::assign::list_of(10)(108) 

const std::set<int> set9 = 
    boost::assign::list_of(4) + set2; 

const std::set<int> set10 = 
    boost::assign::list_of(3)(5) + set2; 

Gibt es eine Möglichkeit, dies ohne Makros zu tun, oder ist das meine einzige Wahl?

Antwort

1

Ein lokales Makro (wie Sie hier haben, der Schlüssel ist die #undef) ist wahrscheinlich die sauberste Lösung, da Sie das Problem darstellen. Allerdings haben Sie nicht viel über gesagt, warum Sie dies tun, und diese Informationen möglicherweise eine bessere Lösung bieten.

würde ich das Makro in der "gegenüberliegenden" Richtung benutzen:

#define COMMON (10)(8) 

const std::set<int> set10 = 
    boost::assign::list_of(3)(5) COMMON; 

#undef COMMON 
2

Irgendwelche Einschränkungen besondere Leistung? Sie könnten nur die Zugabe Sie am Ende verwenden implementieren:

typedef std::set<int> intset; 

intset onion(intset lhscp, const intset &rhs) { 
    lhscp.insert(rhs.begin(), rhs.end()); 
    return lhscp; 
} 

const intset set10 = onion(boost::assign::list_of(2)(5), set2); 
+0

Gute Antwort, aber ist die explizite Umwandlung notwendig? Ich dachte b.a.list_of würde (implizit) in eine Menge konvertieren. –

+0

@Fred: ja, guter Punkt. Tatsächlich kompiliert es nicht * mit * dem Cast für mich, etwas über einen mehrdeutigen Aufruf, weil 'set' zwei 2-arg-Konstruktoren hat. Außerdem weiß ich nicht, warum ich dachte, ich könnte eine Funktion 'union' nennen ;-) –

+0

Hah, ich habe das Problem mit 'union' nicht einmal gesehen, obwohl es hier hervorgehoben ist. –

0

zu stehlen und zwicken leicht Steves Antwort (da ich es nicht ändern kann). Ich denke, die beste Lösung ist, Operator + für Sets zu implementieren.

std::set<int> operator+(std::set<int> lhs, const std::set<int> &rhs) 
{ 
    lhs.insert(rhs.begin(), rhs.end()); 
    return lhs; 
} 

Danach wird es keine Rolle spielt gemacht, ob die Sätze von globalen Konstanten oder Funktionen kommen, sie alle als Argumente an die Konstrukteure gehen kann:

#include <boost/assign/list_of.hpp> 
#include <stdio.h> 
#include <set> 

typedef std::set<int> intset; 
intset operator+(intset lhs, const intset &rhs) 
{ 
    lhs.insert(rhs.begin(), rhs.end()); 
    return lhs; 
} 

const intset set2 = 
    boost::assign::list_of(10)(108); 

const intset set9 = 
    boost::assign::list_of(4) + set2; 

intset get_set11(bool flag) 
{ 
    if(flag) 
    return set2 + boost::assign::list_of(6); 
    else 
    return set9; 
} 


int main(void) 
{ 
    intset my_set(set9 + get_set11(true)); 
    return 0; 
} 
+0

Ich habe mich dagegen entschieden, weil ich mich nicht gerne mit Bedienern anderer Leute auseinandersetze. Aber mit dem Operator in einem vernünftigen Umfang (wie einem Namensraum, der die Sätze enthält), nehme ich nicht an, dass es Schaden anrichtet. Die andere plausible Bedeutung für "+" mit zwei Containern wäre eine Verkettung, die eine Sequenz eines Typs zurückgibt ... –

Verwandte Themen