Domanda

ho bisogno di creare una mappa, da interi a insiemi di tuple, le tuple in un unico insieme hanno la stessa dimensione. Il problema è che la dimensione di una tupla e dei suoi tipi di parametri può essere determinato in fase di esecuzione, non di compilazione. Sto immaginando qualcosa di simile:

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

ma non exctly sicuro di come fare esattamente questo, bossibly utilizzando i puntatori.

Lo scopo di questo è quello di creare relazioni temporanee (tabelle), ognuna con un identificatore univoco (chiave), forse hai un altro approccio.

È stato utile?

Soluzione

Lo scopo è quello di mescolare boost::tuple tipi arbitrari. Se, come dici tu,

  

io sto solo inserisco interi

allora dovreste usare map< int, set< vector< int > > >. (Se fossi in te, mi piacerebbe gettare un po 'a quel typedefs.)

Per rispondere alla domanda iniziale, però, boost::tuple non permette tipi arbitrari in fase di esecuzione. boost::any fa. Tuttavia, any non supporta il confronto quindi c'è un po 'di lavoro, se si desidera utilizzarlo in un set.

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;

Altri suggerimenti

Come un moderno side-note (come le risposte precedenti sono circa 2010), Modelli variadic di oggi sarebbe utile per questo:

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

È possibile memorizzare solo questi insiemi differenti nella stessa collezione, se avete qualche classe base comune per loro. Si potrebbe scrivere un'interfaccia astratta, e quindi implementare che per ogni tipo di tabella / tupla. Il problema è, che di solito tali interfacce tendono ad essere molto disordinato, e si dovrebbe forse avere classe di esplosione se si dispone di molti tipi di tavolo / tuple. Boost.Any potrebbe essere utile per tale interfaccia (poiché è necessario per gestire diversi tipi di dati in modo dinamico).

Se i tipi di parametri hanno qualcosa in comune, che cattura in una classe base astratta e rendere la tupla contiene puntatori a questa classe di base:

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

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

(boost :: tuple omesse per brevità. Non certo perché è necessario un insieme di tuple.)

È quindi possibile ricavare i tipi di parametri concreti MyParamBase e creare e inserirli nella mappa:

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;

Se i tipi di parametri non hanno nulla in comune - non metterli nella stessa mappa. Molto probabilmente non appartengono insieme.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top