2010-03-10 8 views
2

Мне нужно создать карту, от целых чисел до наборов кортежей, кортежи в одном наборе имеют одинаковый размер. Проблема в том, что размер кортежа и его типы параметров можно определить во время выполнения, а не во время компиляции. Я воображая что-то вроде:Кортежи неизвестного размера/типов параметров

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

но не exctly уверен, как именно это сделать, bossibly с использованием указателей.

Целью этого является создание временных отношений (таблиц), каждый из которых имеет уникальный идентификатор (ключ), возможно, у вас есть другой подход.

+0

Просьба уточнить: Один комплект делает только магазин кортежи одного и того же размера , но разные наборы могут иметь разные кортежи? –

+0

Да, в одном наборе хранятся кортежи того же размера, но разные наборы могут иметь разные кортежи. – myahya

+0

Вы хотите наложить ограничение всех элементов в кортеже того же размера во время компиляции? Также, что кортежи могут быть любого типа, в котором один кортеж имеет данные того же типа? – mukeshkumar

ответ

4

Целью boost::tuple является смешивание произвольных типов. Если, как вы говорите,

Я только вставляя целые

, то вы должны использовать map< int, set< vector<int> > >. (Если бы я был вами, я бы бросил на него typedef.)

Чтобы ответить на исходный вопрос, boost::tuple не разрешает произвольные типы во время выполнения. boost::any. Однако, any не поддерживает сравнение, поэтому есть немного больше работы, если вы хотите использовать его в 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; 
0

Вы можете хранить эти разные наборы только в одной коллекции, если для них имеется общий базовый класс. Вы можете написать абстрактный интерфейс, а затем реализовать это для каждого типа таблицы/кортежа. Проблема в том, что обычно такие интерфейсы, как правило, очень грязные, и вы можете иметь класс-взрыв, если у вас много типов таблиц/кортежей. Boost.Any может быть полезен для такого интерфейса (поскольку вам приходится обрабатывать разные типы данных динамически).

0

Если типы параметров имеют что-то общее, что захват в абстрактный базовый класс и сделать кортеж содержат указатели на этом базовом классе:.

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

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

(повышение :: кортежей для краткости опускаем Не знаю, почему вам нужен набор кортежей)

вы можете получить конкретные типы параметров из MyParamBase и создавать и вставлять их в карту:.

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; 

Если ра типы индикаторов не имеют ничего общего - не помещайте их в одну карту. Вполне вероятно, что они не принадлежат друг другу.

1

В современной боковой ноте (как и предыдущие ответы около 2010), современные VARIADIC шаблоны были бы полезны для этого:

template<typename... Args> //Accept any number of arguments and types 
auto MyFunction(std::tuple<Args...> &T)->void 
{ 
    //Do stuff... 
} 
Смежные вопросы