Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Getting a substr from a std::variant<std::string, std::vector<std::string>>> in C++

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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
        }
    }
}

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading