Это моя карта std::map<std::string,ProductInfo> mymap
и вот значения внутри ProductInfo
:
bool isActive = false;
char name[80];
Я уже могу получить доступ к определенной паре ключ-значение (std::string
- ProductInfo
) с помощью ::iterator
, но на самом деле мне нужно свойство name
внутри ProductInfo
Вы знаете, что итератор «указывает» на std::pair
, содержащий ключ и значение? И что ценность находится в second
члене пары? И что это фактическое значение данных? Теперь, как вы думаете, вы могли бы получить доступ к членам вашей структуры?
Предполагая, что у вас есть карта:
std::map<KeyT, ValueT> m;
Значение, на которое указывают ваши итераторы, определяется как:
using value_type = std::pair<KeyT const, ValueT>;
Таким образом, вы используете pair::second
для отображаемого значения:
auto it = m.find("some key");
if (it != m.end()) {
std::cout << "name: " << it->second.name << '\n';
}
Вы хотите получить доступ к свойству name
объекта ProductInfo
внутри карты. Что вам нужно сделать, так это your_map["the key"]->get_name()
, где get_name()
— геттер для name
в ProductInfo
.
Это неверно и не будет компилироваться.
@AnoopRana Намерение не состояло в том, чтобы дать вам код, который компилируется. Намерение состояло в том, чтобы рассказать вам, как получить доступ к свойству класса. Я не совсем понимаю, почему вы пометили ответ как принятый и сказали, что он не скомпилируется. Довольно странно
Я не ОП. Я не принял ваш ответ. ОП и я разные люди. Вы меня с ОПом спутали?
Доступ к ключу std::map
с помощью operator[]
дает нам отображаемый тип, который совпадает с ProductInfo
в вашем примере. Это означает, что вы можете получить доступ к члену данных name
, используя оператор доступа к члену, как показано ниже:
//-----------------------------vvvv---->use member access operator
std::cout << mymap["some key"].name;
Если вы предоставили геттеры для ProductInfo
, вы можете использовать этот геттер, как показано ниже:
std::cout << mymap["some key"].get_name();
Также обратите внимание, что если ключ еще не находится внутри карты, новая пара ключ-значение будет создана и вставлена в карту при использовании operator[]
, поэтому не забудьте инициализировать каждый из элементов данных внутри ProductInfo
.
Чтобы зациклиться на контейнерах, не используйте итераторы (или индексы), если в этом нет явной необходимости, а используйте циклы for на основе диапазона (https://en.cppreference.com/w/cpp/language/range-for). Основанные на диапазоне более удобочитаемы и предотвращают случайный доступ вне границ.
Для удобочитаемости кода вы можете использовать структурированные привязки (https://en.cppreference.com/w/cpp/language/structured_binding) следующим образом:
#include <iostream>
#include <map> // or unordered_map for faster access
#include <string>
struct ProductInfo
{
std::size_t id;
};
int main()
{
// initialize map with 3 entries
std::map<std::string, ProductInfo> m_products
{
{"one",{1}},
{"two",{2}},
{"three",{3}}
};
// range based for loop with structured bindings
for (const auto& [key, product_info] : m_products)
{
std::cout << "key = " << key << ", value = " << product_info.id << "\n";
}
return 0;
}
Также не используйте оператор индекса [], как указано выше. Но используйте по адресу: https://en.cppreference.com/w/cpp/container/map/at. Оператор [] будет вставлять данные, если данные не найдены, и это часто приводит к ошибкам. Функция at будет возвращать данные только в том случае, если они действительно существуют внутри карты.
mymap["some key"].name
?