2016-04-04 5 views
1

Я пытаюсь определить std::unordered_map используя enum class как ключ и определенный класс в качестве ссылочного объекта:станд :: unordered_map с помощью перечисления и определенного класса

std::unordered_map<Dimension, unit, EnumClassHash> SI_Dim; 
SI_Dim[Dimension::MASS] = BaseSIUnits::kilogram; 

Dimension является enum class объявлен в отдельном заголовочный файл в

enum class Dimension{MASS, TIME, LENGTH, TEMPERATURE, CURRENT, QUANTITY, ANGLE, FORCE, ENERGY, POWER, 
       AREA, VOLUME, NONDIMENSIONAL}; 

с EnumClassHash в качестве хэш-функции (которую я могу размещать код, если это необходимо).

BaseSIUnits::kilogram определяется несколько строк выше это как

const unit BaseSIUnits::kilogram = unit(1, "kg", Dimension::MASS); 

который компилирует просто отлично. Но строка SI_Dim[Dimension::MASS] = BaseSIUnits::kilogram; дает мне ошибку. В QtCreator (моя IDE) он говорит «ожидаемое объявление», а g ++ дает ошибку «SI_Dim не называет тип». Ни один из них не имеет для меня никакого смысла. Кроме того, при просмотре строки в QtCreator не выделяются ни Dimension::MASS, ни BaseSIUnits::kilogram (почти как если бы они были непризнанными, хотя я знаю, что они есть). У меня нет большого опыта работы с std :: unordered_map, так что это, вероятно, некоторая простая синтаксическая ошибка, которую я пропускаю. Но синтаксис выглядит правильно для меня на основе примеров, на которые я смотрел.

+1

Извините, я думаю, вопрос здесь не ясен. Мой вопрос в том, есть ли очевидная синтаксическая ошибка, которая мешает компиляции кода. –

+4

У вас есть эта строка 'SI_Dim [Dimension :: MASS] = BaseSIUnits :: kilogram;' вне функции? Вы не можете просто иметь произвольный код в области пространства имен. – Praetorian

+0

У меня есть функция вне функции. Я хочу, чтобы контейнер unordered_map был доступен из других файлов. Как мне это сделать? –

ответ

1

Как отметил Преториан в комментарии, на C++ не может быть кода вне функций (кроме инициализации глобальных/статических переменных). Если вам нужен такой код (то есть код, который не может быть записан как инициализация), вы можете написать функцию init_si_dim, которая должна быть вызвана (один раз) перед использованием. См. this question для способа автоматизации этого с помощью глобального объекта ad-hoc-класса, который выполняет инициализацию в конструкторе.

В отдельном направлении использование неупорядоченной карты для вашего типа enum, кажется немного странным. Учитывая, что у вас так мало значений и не присваиваются значения целого целого значения enum, я думаю, что вам лучше использовать контейнер с произвольным доступом, например, через std::array.

Рассмотрим следующий код

#include <array>                                

enum class dimension{mass, time, length}; 

inline constexpr std::size_t dimension_to_index(dimension d) 
{ 
    return static_cast<std::size_t>(d) - static_cast<std::size_t>(dimension::mass); 
} 

struct foo{}; 

std::array<foo, 1 + dimension_to_index(dimension::length)> v; 

int main() 
{ 
    v[dimension_to_index(dimension::time)]; 
} 

Сначала мы имеем enum, то функцию безопасного преобразования ее значения индексов. Затем мы определяем объект array. Как вы можете видеть в main, теперь можно получить доступ к элементам array через значения enum.

+0

Интересно. Я посмотрю на обе эти альтернативы. –

 Смежные вопросы

  • Нет связанных вопросов^_^