Можно ли обеспечить возможности std :: map и std :: vector в одном классе?
Если нет, что является препятствием?
Обратите внимание, что у меня нет опыта работы с stdlib, поэтому я заранее прошу прощения, если это глупая идея, которую стоит рассмотреть. Я хотел бы представить свой сценарий ниже, чтобы читатель мог понять, почему я рассматриваю эту альтернативу:
Я нахожусь на последних этапах переписывания оболочки C ++ для среды выполнения Python. Идея состоит в том, что мой проект C ++ способен выполнять скрипты Python.
В Python все PyObject
и у меня есть Object
класс, упаковывающий PyObject*
который может указывать на любой из дюжины встроенных типов Python (логическое значение, целое число, число с плавающей запятой, юникод, байты, множество, список, кортеж, словарь, вызываемый модуль).
Я хотел бы отразить типизацию хамелеона Python в C ++.
Так что если обернутым PyObject является {set, list, bytes, unicode, tuple}, то все это последовательности, поэтому я хотел бы иметь возможность делать такие вещи:
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 для быстрого перечисления и т. Д. Begin, end, iterator, const_iterator и т. Д. И {set, list, bytes, unicode, tuple} был получен из этого. Код Вот.
Он также имел класс MapBase, который содержал различные начало, конец, итератор, const_iterator и т. Д. Код Вот.
Я хотел бы объединить эти два контейнера, чтобы все можно было обрабатывать из одного класса 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;
Похоже, эти typedefs должны существовать, чтобы алгоритмы stdlib обрабатывали объект. Но, похоже, мне нужно будет выбрать либо один набор, либо другой.
В четырех примерах указатель typedef отличается в обоих этих случаях.
Какие могут быть решения?
Возможно, я мог бы создать шаблон для Object и использовать метапрограммирование, чтобы разрешить Object и Object, возможно, использовать SFINAE для включения и выключения соответствующих итераторов.
Это выглядит, вероятно, хуже, чем подклассы, но я хотел бы видеть все варианты, которые у меня есть.
Я все еще задаюсь вопросом, есть ли какой-нибудь способ сделать это без необходимости уточнять заранее.
Я не беспокоюсь о создании кода, который может быть использован не по назначению, это обязанность потребителя не делать словарь в списке и т. Д.
(ПРИМЕЧАНИЕ: кроме того, я уже взломал проблему использования A["key"] = B[42]
синтаксис типа для объектов типа последовательности и словарей. Единственная очевидная проблема, с которой я сталкиваюсь, это то, что я хотел бы включить быстрое перечисление: for(auto item:my_obj)
, но я еще не сфокусировался на конечном использовании, и я хотел бы упредить сценарии общего использования).
Если у меня нет чего-то важного, Boost.Container предоставляет flat_map которая в основном является картой, построенной поверх вектора.
Если вы не определили карту нормалей (unordered_) в качестве медленной точки в вашей программе, я бы не решился отойти от нее, хотя …