Карта класса шаблона C ++ - PullRequest
       10

Карта класса шаблона C ++

0 голосов
/ 07 декабря 2011

Я добавляю конструктор и две функции к классу моего предыдущего связанного вопроса C ++ итерируем по шаблону Map , и мне нужна помощь в этом:

  • Что выпосчитать, что этот конструктор делает?
  • Добавление одного значения в начале карты?
  • Я вижу, хотя в соответствующем ключе только адрес в качестве значения после инициализации в main.Что случилось?

Оператор [] должен получить значения для определенного ключа.Однако я не могу использовать его, чтобы получить элементы карты в выводе.Любой намек?

template<class K, class V>
class template_map{
public:
    template_map( V const& val) {
        m_map.insert(my_map.begin(),std::make_pair(std::numeric_limits<K>::min(),val));
    };    

    typedef typename std::map<K,V> TMap;

    TMap my_map;
    typedef typename TMap::const_iterator const_iterator;
    const_iterator begin() const { return my_map.begin(); }
    const_iterator end() const   { return my_map.end(); }
    V const& operator[]( K const& key ) const {
        return ( --my_map.upper_bound(key) )->second;
    }

    ...
};

int main()
{
    interval_map<int,int> Map1 (10);
    //Show the elements of the map?
}

Учтите также, что это должна быть функция, которая вставляет значения в карту.

Ответы [ 3 ]

1 голос
/ 07 декабря 2011

Итератор в map::insert() - это просто подсказка ;по сути, это ничего не значит с точки зрения семантики программы.

Ваш код вставляет значение, переданное через аргумент конструктора, вместе с ключом numeric_limits<K>::min(), то есть наименьшее возможное значение для данного типа ключа,Это скомпилируется, только если numeric_limits специализируется для типа K.

. Также обратите внимание, что если ключ уже существует, соответствующее сопоставленное значение будет не перезаписано, поэтомуФункция вставки будет иметь очень ограниченное использование.

1 голос
/ 07 декабря 2011

Как вы думаете, что делает этот конструктор? Добавление одного значения в начале карты?

Инициализирует карту так, что map[x] == v для любого x. Карта связывает интервалы со значениями, храня внутреннюю карту нормалей с ключом в начале каждого интервала; он инициализируется так, чтобы весь диапазон типа ключа соответствовал начальному значению.

Я вижу в соответствующем ключе только адрес в качестве значения после инициализации в main. Что случилось? Оператор [] должен получить значения для определенного ключа. Однако я не могу использовать его, чтобы получить элементы карты в выводе. Любой намек?

Понятия не имею, о чем ты там спрашиваешь. Если вы попытаетесь, например, cout << Map1[42] << '\n';, то ваша программа должна вывести 10, поскольку это начальное значение, присвоенное всему диапазону целых чисел.

Учтите также, что это должна быть функция, которая вставляет значения в карту.

Поскольку внутренняя карта является общедоступной, вы можете добавить новый интервал на карту с помощью

Map1.my_map.insert(std::make_pair(interval_start, value));

Возможно, было бы более вежливо сделать my_map приватным и предоставить функцию insert() для этого. Вы могли бы также добавить неконстантную перегрузку operator[], которая вставляет новый диапазон и возвращает ссылку на его значение, что-то вроде

V & operator[](K const & key) {
    V const & old_value = (--my_map.upper_bound(key))->second;
    return *my_map.insert(std::make_pair(key, old_value)).first;
}

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

Моя проблема в том, как перебрать карту, чтобы получить все ее элементы и распечатать их в основном. Он показывает мне адрес со значением инициализации объекта.

Помня, что итератор на карте относится к паре ключ / значение (типа std::pair<K,V>), вы должны иметь возможность итерацию на карте следующим образом:

for (auto it = Map1.begin(); it != Map1.end(); ++it) {
    std::cout << it->first << " maps to " << it->second << '\n';
}

(в C ++ 03 вам нужно написать template_map<int,int>::const_iterator вместо auto).

1 голос
/ 07 декабря 2011

Как вы думаете, что делает этот конструктор? Добавление одного значения в начало карты? Я вижу, хотя в соответствующем ключе только адрес как значение после инициализации в main. Что не так?

Добавляет это одно значение на карту. Аргумент итератора является лишь подсказкой: если новый элемент должен быть вставлен сразу после этой позиции, операция может быть завершена быстрее. В противном случае карта должна будет найти правильное место, чтобы вставить новое значение как обычно

Оператор [] должен получить значения для определенного ключа. Однако я не могу использовать его, чтобы получить элементы карты в выход. Любой намек?

upper_bound возвращает итератор для первой пары ключ-значение, где ключ больше аргумента. --upper_bound поэтому возвращает итератор для элемента, ключ которого равен или меньше, чем запрашиваемый ключ. Если upper_bound вернул map.begin(), потому что все ключи больше, чем запрос, уменьшая его, неопределенное поведение.

Здесь вам нужна функция-член find. Вам также необходимо разобраться со случаем, когда ключ не найден (map.end() возвращен), например, сгенерировать исключение.

В качестве альтернативы вы можете реализовать свой operator[] в терминах map::operator[]. Это означает, что функция не может быть константной, потому что карта вставляет новое значение по умолчанию, если ключ не найден.

...