Ошибка при попытке сделать оболочку контейнера карты STL - PullRequest
1 голос
/ 17 октября 2010

Я пытаюсь создать оболочку для контейнера карты STL, чтобы добавить метод const, возвращающий значение, заданное ключом. В map оператор [] не является константным, а find () требует разыменования для получения значения (map.find () -> second). Я основываю некоторые свои «исследования» на Идиоматическом C ++ для чтения с карты констант .

Код на данный момент (все в одном заголовочном файле):

#include <map>
template <typename K, typename V>
class easymap : public std::map<K, V>
{
    //Constructor
    easymap() : std::map<K, V>() {};

    //The get method
    V get(K key)
    {
        std::map<K, V>::const_iterator iter(find(key));
        return iter != end() ? iter->second : V();
    }
};

Когда я пытаюсь скомпилировать это, я получаю следующие ошибки:

In member function `V easymap::get(K)':
    expected `;' before "iter"
`iter' was not declared in this scope
there are no arguments to `end' that depend on a template parameter, so a declaration of `end' must be available|
(if you use `-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)

Имеет ли смысл то, как я пытаюсь сделать это? Если так, как я могу заставить это работать? Если нет, то как бы я добился желаемого эффекта?

Ответы [ 3 ]

3 голосов
/ 17 октября 2010

Не выводить из std::map. Скорее, оберните экземпляр std::map в свой easymap, следуя композиции перед принципом наследования. Помимо всех технических причин, это намного лучше отражает замысел разработки: предоставьте упрощенный API для отображения, скрывающий стандартное:

template<typename K, typename V>
class easymap {
 std::map<K, V> mMap;
public:
  V Get(K Key) const {
   // ...
  }
};
2 голосов
/ 17 октября 2010

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

Причина в том, что ни один из контейнеров STL не имеет деструктора virtual.Итак, если у вас есть указатель, например, std::map<..> *, который указывает на ваш объект (который унаследовал map), один из деструкторов будет не вызываться.Это 100% утечка памяти.

С этим вопросом связан следующий вопрос: Можно ли наследовать реализацию от контейнеров STL, а не от делегата?

2 голосов
/ 17 октября 2010

Вам не хватает параметров шаблона для карты, вы должны указать typename при объявлении итератора (см. здесь ), и по какой-то неизвестной мне причине (вероятно, конфликт пространства имен) вы должныиспользуйте this при звонке end():

template <typename K, typename V>
class easymap : public std::map<K,V>
{
    //Constructor
    easymap() : std::map<K, V>() {};

    //The get method
    V get(K key)
    {
        typename std::map<K, V>::const_iterator iter(find(key));
        return iter != this->end() ? iter->second : V();
    }
};
...