C ++ Как создать гетерогенный контейнер - PullRequest
6 голосов
/ 09 июля 2010

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

Я пытаюсь использовать шаблон класса для каждой точки данных. Затем для каждой точки данных, которую я вижу, я хочу создать новый объект и перенести его обратно в вектор. Для каждого нового типа мне нужно сначала создать новый класс из шаблона. Но я не могу хранить объекты, созданные в любом векторе, поскольку векторы ожидают одинакового типа для всех записей. Типы, которые мне нужно хранить, не могут быть помещены в иерархию наследования. Они не связаны. Также в будущем может быть создано больше типов, и я не хочу менять службу хранения для каждого нового типа. Есть ли способ создать гетерогенный контейнер для хранения этих записей? Спасибо!

Ответы [ 4 ]

9 голосов
/ 09 июля 2010

boost::any уже рекомендовано, но это ни для чего, так что многого от него ожидать не приходится.

Если вы заранее знаете различные типы, лучше использовать boost::variant.

typedef boost::variant<Foo, Bar, Joe> variant_type;

struct Print: boost::static_visitor<>
{
  void operator()(Foo const& f) const { f.print(std::cout); }

  template <class T>
  void operator()(T const& t) const { std::cout << t << '\n'; }
};

void func(variant_type const& v) // not template
{
  boost::apply_visitor(Print(), v); // compile-time checking
                                    // that all types are handled
}
7 голосов
/ 09 июля 2010

В библиотеке boost есть, вероятно, то, что вы ищете (boost :: any).Вы можете свернуть свой собственный, используя метод обернутого указателя, если вы не можете использовать boost ...

4 голосов
/ 09 июля 2010

Проблема с такими контейнерами заключается в том, что когда вы хотите получить доступ к чему-либо в контейнере, вы должны определить его тип и затем каким-то образом привести его к фактическому типу.Это уродливо, неэффективно и подвержено ошибкам, поэтому выбор в C ++ - использовать наследование, если у вас нет веских причин не делать этого - то, чего я никогда не встречал в своей карьере в C ++.

0 голосов
/ 09 июля 2010

Я думал, что вы могли бы просто иметь пару (type, void *) и написать свою собственную функцию pop, которая отбрасывает пустоту * в зависимости от типа, описанного в паре, а затем засунуть их в любой контейнер, который попадется вам на глаза.

...