2014-12-31 2 views
0

Возможно ли предоставить возможности std :: map и std :: vector в одном классе?Контейнер Hybrid (List + Dict) в C++ 11

Если нет, то в чем препятствие?

Обратите внимание, что у меня нет опыта работы со stdlib, поэтому я заранее извиняюсь, если это глупая идея, чтобы даже рассмотреть. Я хотел бы представить свой сценарий ниже, так, чтобы читатель мог понять, почему я рассматриваю эту альтернативу:


Я на заключительных этапах переписывания ++ обертки C вокруг выполнения Python. Идея заключается в том, что мой проект на C++ способен выполнять скрипты Python.

В Python все это PyObject, и у меня есть Object класс обертывание PyObject*, который может быть направлен на любой из десятка встроенных типов языка Python (логическое, целое, с плавающей точкой, Unicode, байт, набор, список, кортеж, словарь, вызываемый, модуль).

Я хотел бы отразить хамелеон Python, набрав на C++.

Так что, если завернут PyObject есть {набор, список байты, юникод, кортеж} все эти последовательности, так что я хотел бы быть в состоянии сделать такие вещи, как:

cout << my_seq[3] 
my_seq[4] = foo 
for(auto item : my_seq) {...} 

И если это словарь, я могу сделать:

my_dict["someKey"] = someValue; 
for(auto kv_pair : my_seq) {...} 

т.д.

Оригинальный проект был класс SeqBase, в котором содержится необходимый STDLIB контейнер механизм для быстрого перечисления и т.д. начало, конец, итератора, const_iterator и т. д. И {set, list, bytes, unicode, tuple}, полученные из этого. Код here.

В нем также был класс MapBase, в котором были разные начальные, конечные, итераторные, const_iterator и т. Д. Код here.

Я хотел бы объединить эти два контейнера, чтобы все можно было обрабатывать из одного класса Object.

Но я не уверен, возможно ли это.

Непосредственного препятствия я вижу:

// SeqBase 
typedef size_t size_type; 
typedef seqref<T> reference; 
typedef T const_reference; 
typedef seqref<T> *pointer; 
typedef int difference_type; 
typedef T value_type; // TMM: 26Jun'01 

// MapBase 
typedef size_t size_type; 
typedef Object key_type; 
typedef mapref<T> data_type; 
typedef std::pair< const T, T > value_type; 
typedef std::pair< const T, mapref<T> > reference; 
typedef const std::pair< const T, const T > const_reference; 
typedef std::pair< const T, mapref<T> > pointer; 

Похоже, эти определения типов должны существовать для того, чтобы алгоритмы STDLIB для обработки объекта. Но похоже, что мне нужно будет выбрать один набор или другой. Например, указатель typedef отличается в обоих случаях.

Какие могут быть решения?

Возможно, я мог бы использовать шаблон Object и использовать метапрограммирование, чтобы разрешить Object и Object, возможно, использовать SFINAE для переключения соответствующих итераторов.

Это выглядит, вероятно, хуже, чем подклассы, но я хотел бы видеть все варианты, которые у меня есть.

Мне все еще интересно, есть ли способ сделать это, не указывая заранее.

Я не обеспокоен производить код, который может использоваться не по назначению, то ответственность потребителя не делать словарь вещи в списке, и т.д.

(Примечание: как в стороне, я уже треснул проблема использования A["key"] = B[42] типа синтаксиса для объектов типа типа и словарей. Единственная очевидная проблема, с которой я сталкиваюсь, заключается в том, что я хотел бы включить быстрое перечисление: for(auto item:my_obj), но я еще не сосредоточился на конечном использовании, и я бы хотел чтобы предугадать общие сценарии использования).

+1

Все, что вам нужно, чтобы быть в состоянии обеспечить 'начать 'и' end', и все, что вам нужно для них, - это предоставить пользовательский итератор. См .: http://www.cs.northwestern.edu/~riesbeck/programming/c++/stl-iterator-define.html – IdeaHat

+0

Что именно вы хотите сделать именно? Является ли бит Python релевантным для вопроса? – Barry

+1

Я не могу разобрать «C++ Python wrapper» - на каком языке происходит перенос? – Eric

ответ

1

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

Если вы не точно определили нормальный (unordered_) карту как медленный момент в вашей программе, я смущался бы отойти от него, хотя ...

Смежные вопросы