简体   繁体   中英

Returning a reference to a map from a function

What is the standard practice of creating a map and returning it to a function as a reference?

In my example, I am just creating a hashmap of the character count from a string, and doing this twice. I see that to return it from the function, the map would have to be created dynamically, otherwise, it would go out of scope and lead to undefined behavior.

However, I don't know how to add to the map, with just a pointer to it. (see code map[*it] += 1; ), and I'm not sure if I'm going about the process in the correct way.

#include <iostream>
#include <map>


std::map<char, int>& createMap(std::string& myString){
    std::map<char, int>* map = new std::map<char, int>();
    for(std::string::iterator it = myString.begin(); it != myString.end(); ++it){
        map[*it] += 1;
    }
    return map;
}

void turnStringsIntoMaps(std::string a, std::string b){
    std::map<char, int> firstMap = createMap(a);
    std::map<char, int> secondMap = createMap(b);
    for(auto it = m.begin(); it != m.end(); ++it){
        std::cout << it->first << " : " << it->second << '\n';
        std::cout << m[it->first] << '\n';
    }
    return true;
}

What is the standard practice of creating a map and returning it to a function as a reference?

There is no "standard practice" of what you want to do, because, frankly, it is unusual.

When you want a function to return a map then make it return a map:

std::map<char, int> createMap(std::string& myString){
    std::map<char, int> myMap;
    // ...
    return myMap;
}

Returning a reference to a local variable is usually a problem:

int& foo() { int x; return x; }

because the reference returned is dangling (the x is long gone when the caller gets the reference). For more on that read here .

It seems you tried to workaround that problem by using dynamic memory allocation. However, this is not necessary. Rather it is to be avoided! Standard containers already manage their memory and most of the time allocating a container on the heap is a code smell.

Without knowing more about why you'd like to do this, you have a couple of options.

#include <map>
#include <iostream>
#include <string>

std::map<char, int> CreateMap(const std::string& myString){
    std::map<char, int> new_map;
    for(const auto& it : myString){
        new_map[it] += 1;
    }
    return std::move(new_map);
}

int main()
{
    auto my_map = CreateMap(std::string("testing"));

    for (const auto& iter: my_map){
        cout << iter.first << "  " << iter.second << endl;
    }

    return 0;
}

The std::move moves the newly created map and hands it back to the caller, so the function no longer has too keep the ref alive.

Another option might be to create the map on the call side, and pass it in by ref:

void CreateMap(const std::string& my_string, std::map<char, int>& my_map);

Usage:

std::map<char, int> my_map;
CreateMap("teststring", my_map);

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM