Say I have the following:
#include <map>
enum class Thing {Zero, One, Two};
class Metadata {};
std::map<Thing, Metadata> extra_info;
void foo() {
extra_info[Thing::Zero] = Metadata();
extra_info[Thing::One] = Metadata();
extra_info[Thing::Two] = Metadata();
}
I would like to ensure that all tags of Thing
are accounted for in extra_info
, in the event that a new tag is added, like Thing::Three
.
I considered always having a tag at the end, LastTag
, and iterating from 0
to LastTag - 2
and verifying that those keys exist in the map, but this seems kludgy. A way to accomplish this at compile time would be best, but I can see this not being possible, at all.
In C#, it's a simple thing to use reflection to get all the enum values, then iterate over these. I think it's telling that I can't find an answer for this with the C++ tag, but I can find answers for Java and C#... Which makes me think this isn't possible.
Sentinel values in enums have been part of many projects to indicate the number of enum values or to delimit a range of user-available enums from the system-defined ones.
In your case you can exploit the fact that a map has unique keys and add a sentinel value (strictly not part of the enum):
enum class Thing { Zero, One, Two, Three, EndSentinel };
class Metadata {};
std::map<Thing, Metadata> extra_info;
typedef std::map<Thing, Metadata>::size_type map_type;
void foo() {
// Can't forget these values
extra_info[Thing::Zero] = Metadata();
extra_info[Thing::One] = Metadata();
extra_info[Thing::Two] = Metadata();
extra_info[Thing::Three] = Metadata();
}
int main() {
foo();
assert(extra_info.size() == (map_type)Thing::EndSentinel);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.