Я реализовал структуру для хранения данных конфигурации, используя конец stl :: map. Я применил оператор [] как:
string& config:operator[] ( const string theKey )
{
ParamMapIter iter;
iter = _configMap.find ( theKey );
if ( iter == _configMap.end() )
{
_configMap[theKey] = ""; // Create a new blank key/value when missing key
}
return _configMap[theKey];
}
поэтому я могу делать такие вещи, как
Conf["key"] = "value";
Теперь я хотел бы сделать этот полу-два мерный, чтобы соответствовать старым конфигурационным файлам Windows с отдельными разделами. например, я могу написать
Conf["section"] ["key"] = "value";
Любые предложения по эффективному внедрению?
Я предполагаю, что реальный вопрос заключается в том, как реализовать двойной индекс. Основная реализация позаботится о фактических деталях, хотя предложения по этому вопросу также были оценены.
Должен ли он соответствовать как Conf["key1"]["key2"] = "bar";
и Conf["key1"] = "foo";
?
Затем вам нужно будет определить раздел, который точно так же, как и ваша текущая конфигурация, за исключением, как показано ниже.
Измените Config [], чтобы вернуть & &.
Сделать оператор перегрузки = взять ключ (т.е. Std :: string), это позволяет реализовать Conf["key1"] = "foo";
в операторе =
_sectionMap[""] = value;
и добавление оператора std :: string для возврата _sectionMap[""]
Это делает ключ раздела "" таким же, как значение Config[key1]
.
std :: map дает вам возможность "создавать, если не существует" в операторе []
Если k не соответствует ключу любого элемента в контейнере, функция вставляет новый элемент с этим ключом и возвращает ссылку на его отображаемое значение. Обратите внимание, что это всегда увеличивает размер контейнера на единицу, даже если для элемента не назначено сопоставленное значение (элемент создается с использованием его конструктора по умолчанию).
Или C++ стандарт [ 23.4.4.3 доступ к элементу карты ]
T & operator [] (const key_type & x);
1 Эффекты: Если на карте нет ключа, эквивалентного x, вставляет значение value_type (x, T()) в карту.
2 Требуется: key_type должен быть CopyInsertable и mapped_type должен быть DefaultInsertable в * это.
3 Возвраты: ссылка на mapped_type, соответствующая x в * this.
4 Сложность: логарифмическая.
T & operator [] (key_type && x);
5 Эффекты: Если на карте нет ключа, эквивалентного x, вставляет в карту значение_значение (std :: move (x), T()).
6 Требуется: mapped_type должен быть DefaultInsertable в * this.
7 Возвраты: ссылка на mapped_type, соответствующую x в * this.
8 Сложность: логарифмическая.
Поэтому, если вы добавляете только функциональность оператора [], вы можете просто сделать
typedef std::map<std::string, std::map<std::string, std::string>> config;
// or in C++11 style
// using config = std::map<std::string, std::map<std::string, std::string>>;
config Conf;
std::map<std::string, std::string>& section = Conf["Section"];
// or again in C++11
// auto §ion = Conf["Section"];
section["key"] = "value";
( const string& theKey )
будет хорошим началом.operator []
должен будет вернуть ссылку на то, что реализуетoperator []
. Кроме того,operator []
std::map
operator []
автоматически вставит инициализированный значением элемент, если ключ не найден. Нет необходимости делать ручную инициализацию.