Возврат ссылки на карту из функции - PullRequest
0 голосов
/ 18 января 2020

Какова стандартная практика создания карты и возврата ее в функцию в качестве справки?

В моем примере я просто создаю хэш-карту количества символов из строки и делаю это дважды. Я вижу, что для возврата из функции карту нужно будет создавать динамически, в противном случае она будет go вне области и приведет к неопределенному поведению.

Однако я не знаю, как добавить на карту, просто указатель на нее. (см. код map[*it] += 1;), и я не уверен, правильно ли я иду в этом процессе.

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

Ответы [ 2 ]

1 голос
/ 18 января 2020

Какова стандартная практика создания карты и возврата ее в функцию в качестве ссылки?

Не существует "стандартной практики" того, что вы хотите сделать, потому что, честно говоря, это необычно.

Если вы хотите, чтобы функция вернула карту, то заставьте ее вернуться карта:

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

Возврат ссылки на локальную переменную обычно является проблемой:

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

, поскольку возвращаемая ссылка свисает (x давно исчезает, когда вызывающая сторона получает ссылку). Подробнее об этом читайте здесь .

Кажется, вы пытались обойти эту проблему, используя динамическое выделение памяти c. Однако в этом нет необходимости. Скорее этого следует избегать! Стандартные контейнеры уже управляют своей памятью, и в большинстве случаев выделение контейнера в куче является запахом кода.

0 голосов
/ 18 января 2020

Не зная больше о том, почему вы хотите это сделать, у вас есть несколько вариантов.

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

std::move перемещает вновь созданную карту и передает ее обратно вызывающей стороне, поэтому функция больше не поддерживает работу.

Другим вариантом может быть создание карты на стороне вызова и передача ее по ссылке:

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

Использование:

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