So I've got a map with a string key and either a string or vector value. I want to cycle through all the string values (whether they're found in a vector or they can be directly checked) in the map and check if they match a given string (it's irrelevant what the string is). If that string matches completely or partly, I will put the map that the string was found in inside a vector.
The issue I'm having is that even though I'm separating strings from vectors using an if conditional the substr
function thinks I'm dealing with a std::variant<std::string, std::vector<std::string>>>
and therefore gives me an error.
The begin functions in the else functions also tell me that variant doesn't have a member called "begin" because of this reason. I'm totally lost, any help would be great.
for (std::unordered_map<std::string,
std::variant<std::string,
std::vector<std::string>>>::iterator h = MyMap.begin();
h != MyMap.end();
h ) {
if (typeid(h->second) == typeid(std::string)) {
std::string MapValueString = h->second.substr(0, TextCtrlValue.length());
if (MapValueString == TextCtrlValue) {
RightSearchResultsVector.insert(RightSearchResultsVector.end(), Maps.begin(), Maps.end());
}
}
else {
for (std::vector<std::string>::iterator f = h->second.begin(); f != h->second.end(); f ) {
// Go through vector and find matching/semi matching strings
}
}
}
CodePudding user response:
Here's how to tell what type a variant holds
std::string* pstr = std::get_if<std::string>(&h->second);
if (pstr != nullptr)
{
// do stuff with string
}
else
{
std::vector<std::string>& vec = std::get<std::vector<std::string>>(h->second);
// do stuff with vector
}
BTW you can simplify this monstrosity
for (std::unordered_map<std::string,
std::variant<std::string,
std::vector<std::string>>>::iterator h = MyMap.begin();
by writing
for (auto h = MyMap.begin();
Judicious use of auto
can greatly improve the readability of your code.