Given a vector of strings which is known at compile-time (and say some numbers they should map to), I wish to create such a map (f.e. unordered_map
) at compile-time. The goal is to start up quickly and perform just look-ups at runtime. Take this example:
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 = // ?
However, constexpr
forbids the use of non-literals. Templating is a solution, however it is a massive headache to implement and maintain.
Does C++(17?) have something in the STL which can aid me in the construction of such map at compile time?
There are no vector
s, string
s, or map
s at compile time. In fact, an object of class type with a non-trivial destructor can't be used in a constexpr
context. So this simply can't be done.
From c++20, you can have non-trivial destructors, so this is possible in principle. As far as I know, only vector
and string
are available in constexpr
contexts though, and even then, all the storage that they allocate, must be deallocated before run-time. So you can't even have a vector
or string
at compile time that you can also use at run-time.
From c++20, you can guarantee that the vector
or string
, or map
is initialized at program-load time though, using the keyword constinit
.
In case you just want to do a complex initialization of a const map
, you can do that with an IIILE (immediately invoked initializing lambda expression) even before c++20. e.g.
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.