В C ++, как мне заполнить карту во время компиляции, учитывая вектор строк? - PullRequest
1 голос
/ 08 апреля 2020

Учитывая вектор строк, который известен во время компиляции (и, скажем, некоторые числа, на которые они должны отображаться), я буду sh создавать такую ​​карту (например, unordered_map) во время компиляции. Цель состоит в том, чтобы быстро запустить и выполнить только поиск во время выполнения. Возьмите этот пример:

enum category {fruit, vegetable};
const std::vector<std::string> fruits = {"apple", "pear", "orange"};
const std::vector<std::string> vegetables = {"cucumber", "zucchini", "tomato"};
const std::unordered_map<std::string, category> lookup_category = // ?

Однако, constexpr запрещает использование не-литералов. Использование шаблонов - это решение, однако его реализация и поддержка - огромная головная боль.

Имеет ли C ++ (17?) Что-то в STL, что может помочь мне в построении такой карты во время компиляции?

1 Ответ

0 голосов
/ 08 апреля 2020

Во время компиляции нет vector с, string с или map с. Фактически, объект типа класса с нетривиальным деструктором не может использоваться в контексте constexpr. Так что это просто невозможно сделать.

Начиная с c ++ 20, вы можете иметь нетривиальные деструкторы, так что это в принципе возможно. Насколько я знаю, только vector и string доступны в constexpr контекстах, хотя и даже тогда, все хранилище, которое они выделяют, должно быть освобождено перед выполнением. Таким образом, вы даже не можете иметь vector или string во время компиляции, которые вы также можете использовать во время выполнения.

Начиная с c ++ 20, вы можете гарантировать, что vector или string или map инициализируется во время загрузки программы, используя ключевое слово constinit.

На случай, если вы просто хотите выполнить сложный инициализация const map, вы можете сделать это с помощью IIILE (немедленно вызвавшего инициализацию лямбда-выражения) еще до c ++ 20. например,

const map<string, int> m = [] {
  map<string,int> x; // construct a map ...
  x["hi"] = 42;  // populate it
  return x;// return it
}();   // and call the expression straight away.
...