Issue with output for nested std::map - c++

std::map<int, std::map<std::string, std::pair<int, std::string>>>mfvs;
I want to output the std::string the first part of inner map.
for (const auto& iter :mfvs)
{
std::cout << iter.second.first << "\n";
}
this gives me an error

iter.second is an std::map, and as such it doesn't have first.
If you want to print the first (with lowest key) element (and you are sure it exists), then do this:
std::cout << iter.second.begin()->first << "\n";
.begin() will return you the first element of the map, and ->first will get its key. If you want to print the value of it as well, something along the lines of the following code will work
auto firstElem = iter.second.begin();
std::cout << firstElem->first << ": " << firstElem->second.first << ", " << firstElem->second.second << "\n";

Related

how to print the contents of the vector to screen in c++ whose each element is pair in a pair

I am working on a assignment in which the elements of the vector of this type vector<pair<string,pair<int,int> > > A .
for(auto it=A.begin();it!=A.end();it++)
cout <<*it.first<<" "<< *it.second.first <<" "<<*it.second.second;
but it is showing errors.
Can anyone help me?
This is much, much simpler with modern C++ language features (C++17):
for (const auto &[s, p] : A)
{
const auto &[a, b] = p;
std::cout << s << " " << a << " " << b << std::endl;
}
If your C++ textbook and/or compiler doesn't cover C++17, it is really worth one's time to update your documentation and/or your compiler to the current C++ standard.
you need to use (*it).first instead of *it.first, because *it.first means a iterator which is it.first, but actually the iterator is (*it).
You can get rid of this problem by using ->, like it->first. Because if you use -> it is lot easier than using *.
vector<pair<string,pair<int,int> > > A;
for(auto it = A.begin(); it != A.end(); it++){
//cout << (*it).first << " " << (*it).second.first << " " << (*it).second.second;
cout << it->first << " " << it->second->first << " " << it->second->second;
}
You can use range-based loop instead of iterators to avoid the problems with *:
for(const auto& itr:A)
{
std::cout<< "Base Pair 1st: "<<itr.first<<" level pair 1st:"<<itr.second.first<<" level pair 2nd "<<itr.second.second;
}

How to print the content of a nested std::unordered_map?

I'm trying to print all the content of an std::unordered_map specified like this:
std::unordered_map<uint64_t, std::unordered_map<uint64_t,uint64_t>> m;
After adding things in the map, I tried the following:
for (auto it=map.begin(); it!=map.end(); it++) {
cout << it->first << it->second << endl;
}
but it is not working.
Since you have nested std::unordered_map, following should work:
for (auto const& i : m) {
for (auto const& j : i.second) {
std::cout << j.first << " " << j.second << std::endl;
}
}
You have to iterate over the nested map as well. And when you work with maps it is very convenient to use a range-based for on top of a structured binding. To avoid these cryptic first and second things:
for (const auto& [key1, value1] : map)
for (const auto& [key2, value2] : value1)
std::cout << key2 << " " << value2 << std::endl;
It works only in C++17 though. If you cannot use it, then you have the answer by NutCracker.
How to print the content of a nested std::unordered_map?
To print nested std::unordered_map use nested range-based for loop.
for (auto const& i: m) {
std::cout << "Key: " << i.first << " (";
for (auto const& j: i.second)
std::cout << j.first << " " << j.second;
std::cout << " )" << std::endl;
}
However, if you want to modify the container's elements:
for (const& i: m) {
for (const& j: i.second)
// Do operations
}

cannot print pointer to element of unordered_map

I've installed CodeBloks and I was testing it with a simple problem.
#include <iostream>
#include <unordered_map>
using namespace std;
int main()
{
unordered_map<int,int> mp;
mp[1]=2;
mp[2]=3;
for(unordered_map<int,int>::iterator it = mp.begin();it!=mp.end();it++)
cout<<*it<<" ";
return 0;
}
I get this error:
cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
Taken from cppreference
for( const auto& n : u ) {
std::cout << "Key:[" << n.first << "] Value:[" << n.second << "]\n";
}
A map (unordered or not) is composed of a key, and a value. You can access it with first and second from the iterator.
The error may be misleading. The actual problem is that unordered map iterates in pairs of keys and values, and there is no << operator for printing these pairs directly.
You can access the key through it->first and the value through it->second:
for(unordered_map<int,int>::iterator it = mp.begin();it!=mp.end();it++)
cout<<it->first << " " << it->second << endl;
Demo.
A map stores key/value-pairs, and it provides a member first (standing for the key) and a member second (standing for the value). Try the following cout...-statement:
cout << it->first << ":" << it->second << " ";
Structured bindings would work nicely for this:
for(auto [first, second] : mp) {
cout << first << '\t' << second << '\n';
}

unordered_map pair of values c++

I am trying to use the unordered_map in C++, such that, for the key I have an int, while for the value there is a pair of floats. But, I am not sure how to access the pair of values. I am just trying to make sense of this data structure. I know to access the elements we need an iterator of the same type as this unordered map declaration. I tried using iterator->second.first and iterator->second.second. Is this the correct way to do access elements?
typedef std::pair<float, float> Wkij;
tr1::unordered_map<int, Wkij> sWeight;
tr1::unordered_map<int, Wkij>:: iterator it;
it->second.first // access the first element of the pair
it->second.second // access the second element of the pair
Thanks for your help and time.
Yes, this is correct, but don't use tr1, write std, since unordered_map is already part of STL.
Use iterators like you said
for(auto it = sWeight.begin(); it != sWeight.end(); ++it) {
std::cout << it->first << ": "
<< it->second.first << ", "
<< it->second.second << std::endl;
}
Also in C++11 you can use range-based for loop
for(auto& e : sWeight) {
std::cout << e.first << ": "
<< e.second.first << ", "
<< e.second.second << std::endl;
}
And if you need it you can work with std::pair like this
for(auto it = sWeight.begin(); it != sWeight.end(); ++it) {
auto& p = it->second;
std::cout << it->first << ": "
<< p.first << ", "
<< p.second << std::endl;
}

c++ vector iterator deference inconsistency

I have the following code. When dereference in line 5, I got wrong value of (*it)->sec. while in line 8, I can obtain correct value. The only difference I noticed is one is inside the for loop, the other is outside the for loop. Is there some subtle point I missing here. I basically want to obtain the member value of the first element in the vector. What's the correct way of obtaining the first (*it)->sec before(outside) the for loop?
void print_allAddresses(std::vector<EntryObj *> EntryObj_vec){
std::cout << "time(sec:microsec) dataType memoryValue" << std::endl;
std::vector<EntryObj *>::iterator it;
it = EntryObj_vec.begin();
std::cout << (*it)->sec << std::endl; //EntryObj_vec.front()->sec also wrong here.
for(it = EntryObj_vec.begin(); it != EntryObj_vec.end(); ++it){
if(!(*it)->parameters.empty()){
std::cout << (*it)->sec << "." << (*it)->microsecond << " ";
std::map<std::string, std::string>::iterator it_map;
for (it_map = (*it)->parameters.begin(); it_map != (*it)->parameters.end(); it_map++){
std::cout << "(" << it_map->first<< ")" << " " << it_map->second << std::endl;
}
}
}
return;
}