Dmitry
Dmitry

Reputation: 2158

c++ : convert std::map<std::string, double> to std::map<std::string_view, double>

Suppose I have a private std::map inside my class std::map<std::string, double>. How can I transform is to std::map<std::string_view, double> to return to the user? I'd like to have the following prototype here

const std::map<std::string_view, double>&
MyClass::GetInternalMap() const;

Upvotes: 2

Views: 236

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 596352

You should not return the new map by const reference. You would be returning a dangling reference to a temp map that was destroyed when GetInternalMap() exits. If you want to return a const reference, then you should return the source map as-is, eg:

const std::map<std::string, double>& MyClass::GetInternalMap() const
{
    return myvalues;
}

Otherwise, return the new map by value instead:

std::map<std::string_view, double> MyClass::GetInternalMap() const;

That being said, a std::map<std::string,double> is not directly convertible to a std::map<std::string_view,double>, so you would have to manually iterate the source map one element at a time, assigning each one to the target map, eg:

std::map<std::string_view, double> MyClass::GetInternalMap() const
{
    std::map<std::string_view, double> result;
    for(auto &p : myvalues) {
        result[p.first] = p.second;
        // or: result.emplace(p.first, p.second);
    }
    return result;
}

Fortunately, a std::pair<std::string,double> is implicitly convertible to a std::pair<std::string_view,double>, so you could simply use the map constructor that takes an iterator range as input, and let map assign the elements for you, eg:

std::map<std::string_view, double> MyClass::GetInternalMap() const
{
    return {myvalues.begin(), myvalues.end()};
}

Upvotes: 5

Related Questions