Frage

Ich brauche eine Karte zu erstellen, aus ganzen Zahlen zu Sätzen von Tupeln, die Tupel in einem einzigen Satz die gleiche Größe hat. Das Problem ist, dass die Größe eines Tupels und seine Parametertypen kann zur Laufzeit bestimmt werden, keine Zeit kompilieren. Ich stelle mir vor so etwas wie:

std::map<int, std::set<boost::tuple> >

aber nicht exctly sicher, wie genau dies zu tun, bossibly Zeiger verwendet werden.

Der Zweck ist, temporäre Beziehungen (Tabellen) zu erstellen, die jeweils mit einer eindeutigen Kennung (key), haben Sie vielleicht einen anderen Ansatz.

War es hilfreich?

Lösung

Der Zweck boost::tuple ist willkürlich Typen zu mischen. Wenn, wie Sie sagen,

  

Ich bin nur ganze Zahlen Einfügen

, dann sollten Sie map< int, set< vector< int > > > verwenden. (Wenn ich Sie wäre, ich einige typedefs auf das werfen würde.)

die ursprüngliche Frage zu beantworten, aber boost::tuple erlaubt keine willkürlichen Typen zur Laufzeit. boost::any tut. Allerdings ist any Vergleich nicht unterstützt, so gibt es ein wenig mehr Arbeit ist, wenn Sie es in einem set verwenden möchten.

typedef vector< boost::any > tuple;
struct compare_tuple { bool operator()( tuple const &l, tuple const &r ) const {
    assert ( l.size() == r.size() );

    for ( tuple::iterator lit = l.begin(), rit = r.begin();
          lit != l.end(); ++ lit, ++ rit ) {
        assert ( lit->type() == rit->type() );

        if ( lit->type() == typeid( foo ) ) { // find the type and perform "<"
            return boost::any_cast<foo>(*lit) < boost::any_cast<foo>(*rit);
        } else if ( lit->type() == typeid( bar ) ) {
            return boost::any_cast<bar>(*lit) < boost::any_cast<bar>(*rit);
        } /* etc; you will need to enumerate all the types you can insert */
    }
} };

typedef std::map< int, std::set< tuple, compare_tuple > > main_map;

Andere Tipps

Als modernes Nebennote (wie in früheren Antworten circa 2010) sind die heutigen Variadische Vorlagen wäre dies nützlich sein:

template<typename... Args> //Accept any number of arguments and types
auto MyFunction(std::tuple<Args...> &T)->void
{
   //Do stuff...
}

Sie können nur diese unterschiedlichen Sätze in der gleichen Sammlung speichern, wenn Sie einige gemeinsame Basisklasse für sie haben. Sie könnten eine abstrakte Schnittstelle, schreiben und dann, dass die Tabelle / Tupel für jede Art umzusetzen. Das Problem ist, dass in der Regel solche Schnittstellen sind in der Regel sehr chaotisch sein, und Sie würden möglicherweise Klasse-Explosion, wenn Sie viele Arten von Tabellen / Tupel haben. Boost.Any für eine solche Schnittstelle nützlich sein könnte (da Sie verschiedene Datentypen handhaben müssen dynamisch).

Wenn die Parametertypen etwas gemeinsam haben, erfassen, dass in eine abstrakte Basisklasse und macht die Tupel Zeiger auf diese Basisklasse enthält:

class MyParamBase {
public:
    virtual int getFoo() = 0;
    virtual void setFoo(int) = 0;
};

std::map<int, std::set<MyParamBase*> > container;

(boost :: tuple der Kürze halber weggelassen. Nicht sicher, warum Sie eine Menge von Tupeln benötigen.)

Sie können dann die konkreten Parametertypen von MyParamBase abzuleiten und erstellen und sie in die Karte einfügen:

class SomeParam: MyParamBase {
public:
    virtual int getFoo() { ... }
    virtual void setFoo(int a) { ... }
};

std::set<MyParamBase*> some_set;
some_set.insert(new SomeParam());
container[123] = some_set;

Wenn die Parametertypen nichts gemein haben - legen Sie sie nicht in die gleiche Karte. Sehr wahrscheinlich, dass sie nicht zusammengehören.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top