Неупорядоченная карта STL с пользовательским типом ключа

0

У меня есть некоторый код, связанный с графиком C++, который работает с использованием структуры std::map. Я не нуждаюсь в том, чтобы элементы строго упорядочивались, и поэтому я хотел бы перейти к структуре std::unordered_map.

Соответствующая часть кода выглядит следующим образом:

typedef unsigned size_type;

struct internal_edge{
 size_type node1_uid;
 size_type node2_uid;
};

std::map<size_type, internal_edge> edges_;

Когда я переключаюсь на std::unordered_map, компилятор жалуется на "слишком мало аргументов шаблона для шаблона класса" unordered_map "". Я попробовал поместить хэшер и компаратор по умолчанию (edit: thanks @rems4e для исправленной версии):

struct size_type_hash {
    std::size_t operator()(const size_type& k) const
    {
        return std::hash<size_type>()(k);
    }
};

struct size_type_equal {
    bool operator()(const size_type& lhs, const size_type& rhs) const
    {
        return lhs == rhs;
    }
};

std::unordered_map<size_type, internal_edge, size_type_hash, size_type_equal> edges_;

Это все равно дает то же сообщение об ошибке:

./Graph.hpp:384:9: error: too few template arguments for class template 'unordered_map'
   std::unordered_map<size_type, internal_edge, size_type_hash, size_type_equal> edges_;
        ^
/usr/bin/../lib/c++/v1/__hash_table:86:28: note: template is declared here
    class _LIBCPP_TYPE_VIS unordered_map;
                           ^
In file included from viewer.cpp:21:
./Graph.hpp:384:82: warning: private field 'edges_' is not used [-Wunused-private-field]
   std::unordered_map<size_type, internal_edge, size_type_hash, size_type_equal> edges_;

Мой файл Makefile:

...
CXX := $(shell which clang++) -stdlib=libc++ -std=gnu++11
...

И вывод clang++:

Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix

Я как бы застрял там, так как это одна из моих первых экскурсий в мир C++. Любые идеи о том, как создать неупорядоченный конструктор карт?

  • 1
    Это просто работает: coliru.stacked-crooked.com/a/7c0c4386647fafae
  • 0
    Как const size_type может быть "aka const unsigned int ", когда вы ссылаетесь на size_type::first и size_type::second ? Похоже, вы думаете, что это пара.
Показать ещё 4 комментария
Теги:
c++11
unordered-map
stl

2 ответа

2
Лучший ответ

Стандартные заголовки библиотек могут содержать друг друга неопределенными способами, а заголовки также могут содержать дополнительные объявления, поэтому ошибка (если таковая имеется), которую вы получаете, когда вы забываете включать заголовок, не обязательно то, что вы ожидаете.

Здесь, например, один из включенных заголовков включал внутренний заголовок <__hash_table> в libc++, который содержит декларацию forward unordered_map. Это форвардное объявление не содержит аргументов шаблона по умолчанию (он не может иметь аргументы по умолчанию, поскольку правила языка не позволяют вам давать аргументы по умолчанию шаблона в двух объявлениях в той же области, поэтому, если это так, а затем пользователь также включил <unordered_map> - который должен предоставить аргументы по умолчанию - компилятор будет жаловаться), поэтому, когда компилятор видит, что вы пытаетесь использовать unordered_map с аргументами по умолчанию, он жалуется, что у вас слишком мало аргументов шаблона, а не unordered_map не объявлен.

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

Исправить это просто: включить <unordered_map>. Там нет необходимости в пользовательском хэшере или компасере для unsigned - просто используйте стандартные.

  • 0
    +1: C ++ действительно отстой во многих отношениях.
-1

Вероятно, ваша проблема связана с плохой копией и вставкой, поскольку вы пытаетесь получить first и second поля из переменных size_type, которые являются typedef для unsigned int.

Замените свои хэш-функции этими и ваш код будет скомпилирован:

struct size_type_hash {
    std::size_t operator()(const size_type& k) const
    {
        return std::hash<size_type>()(k);
    }
};

struct size_type_equal {
    bool operator()(const size_type& lhs, const size_type& rhs) const
    {
        return lhs == rhs;
    }
};

Чтобы быть уверенным, не забудьте включить заголовок в свой файл.

  • 0
    Спасибо за разъяснения. После внесения этих изменений другие ошибки исчезли, но я все еще застрял с «ошибкой: слишком мало аргументов шаблона для шаблона класса« unordered_map »»
  • 0
    Исправленный код отлично скомпилирован на моей стороне. Вы уверены, что даете нам свою рабочую версию? Какой компилятор вы используете и в какой версии?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню