Pregunta

Es necesario crear un mapa, a partir de los números enteros a conjuntos de tuplas, las tuplas de un único conjunto tienen el mismo tamaño. El problema es que el tamaño de una tupla y sus tipos de parámetros puede ser determinado en tiempo de ejecución, no en tiempo de compilación. Me estoy imaginando algo como:

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

pero no exctly seguro de cómo hacer exactamente esto, bossibly el uso de punteros.

El propósito de esto es crear relaciones temporales (tablas), cada uno con un identificador único (clave), puede ser que tenga otro enfoque.

¿Fue útil?

Solución

El propósito de boost::tuple es mezclar tipos arbitrarios. Si, como usted dice,

  

Sólo estoy insertando enteros

, entonces debería usar map< int, set< vector< int > > >. (Si yo fuera tú, me lanzo algunas typedefs en eso.)

Para responder a la pregunta original, sin embargo, no permite boost::tuple tipos arbitrarios en tiempo de ejecución. boost::any hace. Sin embargo, any no admite comparación así que hay un poco más de trabajo si se desea utilizarlo en 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;

Otros consejos

Como nota lateral moderna (como las respuestas anteriores son alrededor del año 2010), plantillas variadic de hoy sería útil para esto:

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

Sólo puede almacenar estos conjuntos diferentes en la misma colección si tiene alguna clase base común para ellos. Se podría escribir una interfaz abstracta, y luego poner en práctica que para cada tipo de mesa / tupla. El problema es, que por lo general tales interfaces tienden a ser muy desordenado, y que posiblemente tendría clase de explosión si tiene muchos tipos de mesa / tuplas. Boost.Any podría ser útil para una interfaz tal (ya que hay que manejar diferentes tipos de datos de forma dinámica).

Si los tipos de parámetros tienen algo en común, capturar esto en una clase base abstracta y hacer que la tupla contiene punteros a esta clase de base:

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

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

(boost :: tupla omitido por razones de brevedad. No sé por qué se necesita un conjunto de tuplas.)

A continuación, puede derivar los tipos de parámetros concretos de MyParamBase y crear e insertarlos en el mapa:

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;

Si los tipos de parámetros no tienen nada en común - no ponerlos en el mismo mapa. Es muy probable que no pertenecen juntos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top