Можно ли установить конструктор по умолчанию в значения `std :: map <T1, T2>`? - PullRequest
3 голосов
/ 11 ноября 2011

Итак, я хочу создать простую карту std::map<T1, std::string>, и у меня есть функция, которая возвращает std::string Я хочу как-то связать создание элементов в std :: map с моей функцией, чтобы при вызове my_map[some_new_element] моя функция вызывается и его возвращаемое значение устанавливается для ключа some_new_element. Возможна ли такая вещь и как это сделать?

Ответы [ 2 ]

3 голосов
/ 11 ноября 2011

Вы можете обернуть саму карту или , тип значения или , оператор [].

Последняя обёртка будет самой простой:

template <typename T>
std::string& get_default(std::map<T, std::string>& map, const T& 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::string& wrapped_string)
        : wrapped_string(wrapped_string) {}
    operator const std::string&() const { return wrapped_string; }
    operator std::string&() { return wrapped_string; }
};

Обтекание карты займет немного больше времени, так как вам придется дублировать весь интерфейс, включая typedefs. Примечание: этот код не проверен, рассматривайте его как доказательство концепции, чтобы направить вас в правильном направлении.

2 голосов
/ 11 ноября 2011

А как насчет небольшого класса-обёртки для std::string?

class StringWrapper {

    StringWrapper() { //... your code
    }

    operator std::string&() { return m_string; } // or something like that
private:
    std::string m_string;
};

Теперь вы используете следующий тип карты:

std::map<T1, StringWrapper> mymap;

В конструкторе StringWrapper вы можете определить пользовательские действия. Он вызывается, когда вы вставляете элемент в карту.

...