For starters, try not to use a string as a key. Use a unique key or a hash (analyze whether you can predict a hash collision may happen or not under your control).
What would you recommend?
Second, what are you going to do most often? Iterate through them or find/query them? How often will you query/iterate per second (or per frame if applies).
I guess you're not going to be inserting/removing very often once you booted your application.
Third. How much is "great number devices". If that's 30 devices, a plain vector with linear search would work (and would work faster because of better cache coherence).
But if you don't iterate or look too often, it won't matter much whether you choose a vector or a map.
If you're going to handle around 1000 devices and 10 subclasses, then take in mind map's find complexity is logarithmic. Creating 10 maps of 100 devices each will result in poorer performance compared to a single map of a 1000 devices.
If you're going to have 30000 devices with 3 subclasses, it won't make much difference whether you choose 1 map, or 3 maps.
Fourth, if you're going to iterate very often through 1000s of devices per second, and will rarely insert/remove, then I'll suggest a sorted vector using std::lower_bound & std::vector::insert
Fifth, you may prefer OOP inheritance and virtual tables instead of casting to the correct derived type.