In the tool I wrote to generate UCL wrappers from schemas for config files I am using exactly this pattern to provide a compile-time string-to-type map. You can then use this to define an adaptor that converts a configuration object to a C++ type based on the value of a field of that the configuration object, which you can then use with a visitor pattern to dispatch the object to a handler of the correct type. The same underlying machinery lets me convert from a string to an enum value with a completely declarative construct.
The code that the compiler generates for all of these is very efficient because all of the strings are very short and so most compares can be a single in-register operation. I was planning on optimising this later but in the end I learned to just trust the compiler: it generated such good code that I probably could improve it doing anything more clever.