#c #stl #map #std
#c #stl #словарь #std
Вопрос:
Итак, я хочу создать простую карту, std::map<T1, std::string>
и у меня есть функция, которая возвращает std::string
Я хочу каким-то образом связать создание элемента в std::map с моей функцией, чтобы при my_map[some_new_element]
вызове вызывалась моя функция, а для ее возврата устанавливалось значение для some_new_element
ключа. Возможно ли такое и как это сделать?
Комментарии:
1. Конечно, возможно с помощью какой-то оболочки, но вопрос в том, почему ? В чем смысл карты? Если вам нужно только фиксированное значение, почему бы не вызвать функцию напрямую?
2. Принимает ли ваша функция параметры?
Ответ №1:
Вы можете обернуть саму карту или тип значения или operator[].
Последняя оболочка будет самой простой:
template <typename T>
std::stringamp; get_default(std::map<T, std::string>amp; map, const Tamp; key) {
auto it = map.find(key);
if (it == map.end()) {
return map[key] = create_default_value();
} else {
return *it;
}
}
Тип значения также не должен быть слишком сложным:
struct default_string {
std::string wrapped_string;
default_string() : wrapped_string(create_default_value()) {}
explicit default_string(const std::stringamp; wrapped_string)
: wrapped_string(wrapped_string) {}
operator const std::stringamp;() const { return wrapped_string; }
operator std::stringamp;() { return wrapped_string; }
};
Перенос карты потребует немного больше работы, так как вам пришлось бы дублировать весь интерфейс, включая typedefs. Примечание: этот код не тестировался, рассматривайте его как подтверждение концепции, чтобы направить вас в правильном направлении.
Комментарии:
1. 1 для
get_default
функции мне не очень нравится создавать новый тип только для принудительного использования одного конкретного конструктора…
Ответ №2:
Как насчет небольшого класса-оболочки для std::string
?
class StringWrapper {
StringWrapper() { //... your code
}
operator std::stringamp;() { return m_string; } // or something like that
private:
std::string m_string;
};
Теперь вы используете следующий тип карты:
std::map<T1, StringWrapper> mymap;
В конструкторе StringWrapper
вы можете определять пользовательские действия. Он вызывается, когда вы вставляете элемент в свою карту.