Implementing BFS using C++ - c++

I am trying to implement BFS in C++, Here is the code.
#include <iostream>
#include <list>
#include <string>
#include <limits>
#include <map>
int infinity=std::numeric_limits<int>::max();
struct Node{
int value;
int distance;
std::string color;
Node(int val):
value(val),
distance(infinity),
color("white")
{}
};
//using AdjList = std::map<Node*,std::list<Node*>>;
typedef std::map<Node*,std::list<Node*>> AdjList;
AdjList create_graph()
{
Node* n1 = new Node(1);
Node* n2 = new Node(2);
Node* n3 = new Node(3);
Node* n4 = new Node(4);
Node* n5 = new Node(5);
Node* n6 = new Node(6);
Node* n7 = new Node(7);
Node* n8 = new Node(8);
AdjList m;
m[n1] = {n2, n5};
m[n2] = {n1, n6};
m[n3] = {n4, n6, n7};
m[n4] = {n3, n7, n8};
m[n5] = {n1};
m[n6] = {n2, n3, n7};
m[n7] = {n3, n4, n6, n8};
m[n8] = {n4, n7};
return m;
}
void bfs(const AdjList& m, Node* n1)
{
std::list<Node*> queue;
queue.push_back(n1);
unsigned count = 0;
while (!queue.empty())
{
auto n = queue.front();
std::cout << n->value << std::endl;
queue.pop_front();
std::cout << *(m[n].begin()) << std::endl;
for(auto it = m[n].begin(); it != m[n].end(); ++it)
{
if ((*it)->color != "black")
queue.push_back(*it);
}
n->color = "black";
n->distance = count;
++count;
}
}
On trying to compile with gcc, I receive the following error messages.
bfs.cpp: In function ‘void bfs(const AdjList&, Node*)’:
bfs.cpp:59:27: error: passing ‘const AdjList {aka const std::map<Node*, std::list<Node*> >}’ as ‘this’ argument of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = Node*; _Tp = std::list<Node*>; _Compare = std::less<Node*>; _Alloc = std::allocator<std::pair<Node* const, std::list<Node*> > >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = std::list<Node*>; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = Node*]’ discards qualifiers [-fpermissive]
std::cout << *(m[n].begin()) << std::endl;
^
bfs.cpp:60:20: error: passing ‘const AdjList {aka const std::map<Node*, std::list<Node*> >}’ as ‘this’ argument of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = Node*; _Tp = std::list<Node*>; _Compare = std::less<Node*>; _Alloc = std::allocator<std::pair<Node* const, std::list<Node*> > >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = std::list<Node*>; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = Node*]’ discards qualifiers [-fpermissive]
for(auto it = m[n].begin(); it != m[n].end(); ++it)
^
bfs.cpp:60:40: error: passing ‘const AdjList {aka const std::map<Node*, std::list<Node*> >}’ as ‘this’ argument of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = Node*; _Tp = std::list<Node*>; _Compare = std::less<Node*>; _Alloc = std::allocator<std::pair<Node* const, std::list<Node*> > >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = std::list<Node*>; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = Node*]’ discards qualifiers [-fpermissive]
for(auto it = m[n].begin(); it != m[n].end(); ++it)
I am not sure what is wrong. Please point out the mistake.

std::map::operator[] is non-const because it will insert elements if needed:
int main()
{
std::map<std::string, std::string> m;
m["new element"] = "1";
}
The problem is that m is a const AdjList&, on which you cannot call non-const member functions. You can use std::map::find() instead:
auto itor = m.find(n);
if (itor != m.end())
std::cout << *(m->second.begin()) << std::endl;

Two C++11 features will make your life much easier
the at() const function for maps, which is like [] but throws an out of range exception if the key is not there, instead of adding a new item to the map.
the for loop over containers
So :
for (auto it : m.at(n)) {
if (it->color != "black")
queue.push_back(it);
}

Related

Runtime error creating map c++ visual studio compiler

I'm doing the task from site https://www.codingame.com/ide/puzzle/mean-max. As I understood it uses VS compiler. I written the code below to solve the task.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <cmath>
using namespace std;
struct point {
int x, y;
};
struct tri {
double d;
int times;
point coords;
};
int main()
{
// game loop
while (1) {
map<point, int> w;
point coords;
float mass;
int friction;
int throttle;
vector<tri> a;
int my_score;
cin >> my_score; cin.ignore();
int enemy_score_1;
cin >> enemy_score_1; cin.ignore();
int enemy_score_2;
cin >> enemy_score_2; cin.ignore();
int my_rage;
cin >> my_rage; cin.ignore();
int enemy_rage_1;
cin >> enemy_rage_1; cin.ignore();
int enemy_rage_2;
cin >> enemy_rage_2; cin.ignore();
int unit_count;
cin >> unit_count; cin.ignore();
for (int i = 0; i < unit_count; i++) {
int unit_id;
int unit_type;
int player;
float mass;
int radius;
int x;
int y;
int vx;
int vy;
int extra;
int extra_2;
cin >> unit_id >> unit_type >> player >> mass >> radius >> x >> y >> vx >> vy >> extra >> extra_2; cin.ignore();
if (unit_type == 4) {
if (!w.count({x, y}))
w[{x,y}] = 0;
w[{x,y}]++;
}
if (unit_id == 0) {
coords = {x, y};
}
}
for (auto p : w) {
a.push_back(tri {sqrt(pow(coords.x - p.first.x, 2) + pow(coords.y - p.first.y, 2)),
p.second, p.first});
}
// sort(a.begin(), a.end(), [&](tri& t1, tri& t2) {
// return t1.d > (throttle / mass) && t2.d <= (throttle / mass);
// });
for (auto p : a) {
cerr << p.d << ' ';
}
int l = -1, r = 300;
while (l + 1 < r) {
int m = (l + r) >> 1;
if (m / mass >= a[0].d) {
r = m;
} else {
l = m;
}
}
throttle = r;
// Write an action using cout. DON'T FORGET THE "<< endl"
// To debug: cerr << "Debug messages..." << endl;
cout << a[0].coords.x << ' ' << a[0].coords.y << ' ' << throttle << endl;
cout << "wait" << endl;
cout << "WAIT" << endl;
}
}
It throws an runtime error:
In file included from /usr/include/c++/10/string:48,
from /usr/include/c++/10/bits/locale_classes.h:40,
from /usr/include/c++/10/bits/ios_base.h:41,
from /usr/include/c++/10/ios:42,
from /usr/include/c++/10/ostream:38,
from /usr/include/c++/10/iostream:39,
from /tmp/Answer.cpp:1:
/usr/include/c++/10/bits/stl_function.h: In instantiation of ‘constexpr bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = point]’:
/usr/include/c++/10/bits/stl_map.h:519:32: required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = point; _Tp = int; _Compare = std::less<point>; _Alloc = std::allocator<std::pair<const point, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = point]’
/tmp/Answer.cpp:71:28: required from her
...
_Tp> std::operator<(const _Up&, const std::optional<_Tp>&)’
1173 | operator<(const _Up& __lhs, const optional<_Tp>& __rhs)
| ^~~~~~~~
/usr/include/c++/10/optional:1173:5: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/10/string:48,
from /usr/include/c++/10/bits/locale_classes.h:40,
from /usr/include/c++/10/bits/ios_base.h:41,
from /usr/include/c++/10/ios:42,
from /usr/include/c++/10/ostream:38,
from /usr/include/c++/10/iostream:39,
from /tmp/Answer.cpp:1:
/usr/include/c++/10/bits/stl_function.h:386:20: note: ‘const point’ is not derived from ‘const std::optional<_Tp>’
386 | { return __x < __y; }
| ~~~~^~~~~
In file included from /usr/include/c++/10/map:61,
from /tmp/Answer.cpp:5:
/usr/include/c++/10/bits/stl_map.h:1501:5: note: candidate: ‘template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator<(const std::map<_Key, _Tp, _Compare, _Allocator>&, const std::map<_Key, _Tp, _Compare, _Allocator>&)’
1501 | operator<(const map<_Key, _Tp, _Compare, _Alloc>& __x,
| ^~~~~~~~
/usr/include/c++/10/bits/stl_map.h:1501:5: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/10/string:48,
from /usr/include/c++/10/bits/locale_classes.h:40,
from /usr/include/c++/10/bits/ios_base.h:41,
from /usr/include/c++/10/ios:42,
from /usr/include/c++/10/ostream:38,
from /usr/include/c++/10/iostream:39,
from /tmp/Answer.cpp:1:
/usr/include/c++/10/bits/stl_function.h:386:20: note: ‘const point’ is not derived from ‘const std::map<_Key, _Tp, _Compare, _Allocator>’
386 | { return __x < __y; }
| ~~~~^~~~~
In file included from /usr/include/c++/10/map:62,
from /tmp/Answer.cpp:5:
/usr/include/c++/10/bits/stl_multimap.h:1166:5: note: candidate: ‘template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator<(const std::multimap<_Key, _Tp, _Compare, _Allocator>&, const std::multimap<_Key, _Tp, _Compare, _Allocator>&)’
1166 | operator<(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
| ^~~~~~~~
/usr/include/c++/10/bits/stl_multimap.h:1166:5: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/10/string:48,
from /usr/include/c++/10/bits/locale_classes.h:40,
from /usr/include/c++/10/bits/ios_base.h:41,
from /usr/include/c++/10/ios:42,
from /usr/include/c++/10/ostream:38,
from /usr/include/c++/10/iostream:39,
from /tmp/Answer.cpp:1:
/usr/include/c++/10/bits/stl_function.h:386:20: note: ‘const point’ is not derived from ‘const std::multimap<_Key, _Tp, _Compare, _Allocator>’
386 | { return __x < __y; }
What do I need to fix? It will work at AppleClang, which I used most. And I had not experience with VS compiler before.
std:: map requires operator< for Key type. You should consider std::unordered_map.

Error using std::set to implement a sparse 3D grid

I'm trying to implement a sparse 3D grid with std::set container, but I can't understand the error returned from the compiler, this is the minimal example I'm trying to run:
#include <iostream>
#include <vector>
#include <limits>
#include <set>
#include <Eigen/Core>
using namespace std;
class Cell {
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
Cell(const Eigen::Vector3i idx=Eigen::Vector3i::Zero()):_idx(idx) {
_center = Eigen::Vector3f::Zero();
_parent = 0;
_distance = std::numeric_limits<int>::max();
}
inline bool operator < (const Cell& c){
for (int i=0; i<3; i++){
if (_idx[i]<c._idx[i])
return true;
if (_idx[i]>c._idx[i])
return false;
}
return false;
}
inline bool operator == (const Cell& c) { return c._idx == _idx;}
private:
Eigen::Vector3i _idx;
Eigen::Vector3f _center;
vector<Eigen::Vector3f> _points;
Cell* _parent;
size_t _closest_point;
float _distance;
int _tag;
};
int main(int argc, char* argv[]) {
set<Cell> grid;
float max = 1, min = -1;
int dim = 5;
float delta = (max-min)/(dim-1);
for(int k = 0; k < dim; k++)
for(int j = 0; j < dim; j++)
for(int i = 0; i < dim; i++)
grid.insert(Cell(Eigen::Vector3i(i,j,k)));
return 0;
}
and this is the compiler error:
In file included from /usr/include/c++/4.8/string:48:0,
from /usr/include/c++/4.8/bits/locale_classes.h:40,
from /usr/include/c++/4.8/bits/ios_base.h:41,
from /usr/include/c++/4.8/ios:42,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from /home/dede/build/sparse_grid/main.cpp:1: /usr/include/c++/4.8/bits/stl_function.h: In instantiation of 'bool
std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp =
Cell]': /usr/include/c++/4.8/bits/stl_tree.h:1324:11: required from
'std::pair
std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::_M_get_insert_unique_pos(const key_type&) [with _Key = Cell; _Val = Cell; _KeyOfValue = std::_Identity; _Compare = std::less; _Alloc = std::allocator; std::_Rb_tree<_Key,
_Val, _KeyOfValue, _Compare, _Alloc>::key_type = Cell]' /usr/include/c++/4.8/bits/stl_tree.h:1377:47: required from
'std::pair, bool> std::_Rb_tree<_Key,
_Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_Arg&&) [with _Arg = Cell; _Key = Cell; _Val = Cell; _KeyOfValue = std::_Identity; _Compare = std::less; _Alloc =
std::allocator]' /usr/include/c++/4.8/bits/stl_set.h:472:40:
required from 'std::pair, _Compare, typename
_Alloc::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(std::set<_Key, _Compare, _Alloc>::value_type&&) [with _Key = Cell; _Compare = std::less; _Alloc = std::allocator; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename
_Alloc::rebind<_Key>::other>::const_iterator = std::_Rb_tree_const_iterator; std::set<_Key, _Compare,
_Alloc>::value_type = Cell]' /home/dede/build/sparse_grid/main.cpp:53:57: required from here
/usr/include/c++/4.8/bits/stl_function.h:235:20: error: passing 'const
Cell' as 'this' argument of 'bool Cell::operator<(const Cell&)'
discards qualifiers [-fpermissive]
{ return __x < __y; }
^ make[2]: * [CMakeFiles/sparse_grid.dir/main.cpp.o] Error 1 make[1]: *
[CMakeFiles/sparse_grid.dir/all] Error 2 make: *** [all] Error 2
I would really appreciate if someone could tell me what I'm doing wrong.
Thanks,
Federico
You should declare your boolean operator functions as const members:
inline bool operator < (const Cell& c) const {
// ^^^^^
for (int i=0; i<3; i++){
if (_idx[i]<c._idx[i])
return true;
if (_idx[i]>c._idx[i])
return false;
}
return false;
}
inline bool operator == (const Cell& c) const { return c._idx == _idx;}
// ^^^^^
Otherwise these cannot be used with rvalue objects of Cell.
You have defined operator < in Cell, but the error says it wants bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = Cell]. Notice you should make your member function const.
You could provide a non-member function for less, which can use your member function, once the it is const.
bool operator <(const Cell &a, const Cell &b)
{
return a < b;
}
However, std::less will provide this for you, provided your member function is const.
You have declared your Parameters for > and == operators overloads as const and you are passing a temporary.
Just create a temporary Object of Cell within the loop and insert it in cell
Do it like this :
for(int k = 0; k < dim; k++)
for(int j = 0; j < dim; j++)
for(int i = 0; i < dim; i++)
{
Eigen::Vector3i(i,j,k) eigenVec;
Cell cell(eigenVec);
grid.insert(cell);
}
Your compilation should succeed.

Compiling error when insert pair into set [duplicate]

This question already has answers here:
problems with c++ set container
(2 answers)
Closed 6 years ago.
I can't understand why g++ returns error like this:
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_pair.h: In function 鈥榖ool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&) [with _T1 = int, _T2 = stop]鈥
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_function.h:227: instantiated from 鈥榖ool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = std::pair<int, stop>]鈥
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_tree.h:921: instantiated from 鈥榮td::pair<typename std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::insert_unique(const _Val&) [with _Key = std::pair<int, stop>, _Val = std::pair<int, stop>, _KeyOfValue = std::_Identity<std::pair<int, stop> >, _Compare = std::less<std::pair<int, stop> >, _Alloc = std::allocator<std::pair<int, stop> >]鈥
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_set.h:321: instantiated from 鈥榮td::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const _Key&) [with _Key = std::pair<int, stop>, _Compare = std::less<std::pair<int, stop> >, _Alloc = std::allocator<std::pair<int, stop> >]鈥
newGraph.cpp:48: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_pair.h:104: error: no match for 鈥榦perator<鈥in 鈥榑_x->std::pair<int, stop>::second < __y->std::pair<int, stop>::second鈥
Here is my code:
#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <set>
#include <utility> // for pair
#include <algorithm>
#include <iterator>
const int max_weight = INT_MAX;
struct stop {
std::string name_stop;
int id_stop;
bool operator !=(const stop &rhs) const
{
return ((id_stop != rhs.id_stop) || (name_stop != rhs.name_stop));
}
};
struct neighbor {
stop target;
int weight;
neighbor(stop arg_target, int arg_weight) : target(arg_target), weight(arg_weight) { }
};
std::list<stop> dijkstraComputeAndGetShortestPaths(stop src,
stop dst,
std::vector< std::vector<neighbor> > &adj_list,
std::vector<int> &min_distance,
std::vector<stop> &previous)
{
stop fake_stop;
fake_stop.id_stop = INT_MAX;
fake_stop.name_stop = "Null";
std::list<stop> path;
int n = adj_list.size();
min_distance.clear();
min_distance.resize(n, max_weight);
min_distance[src.id_stop] = 0;
previous.clear();
previous.resize(n, fake_stop);
std::set< std::pair< int, stop > > vertex_queue;
vertex_queue.insert(std::make_pair(min_distance[src.id_stop], src));
while (!vertex_queue.empty())
{
int dist = vertex_queue.begin()->first;
stop u = vertex_queue.begin()->second;
vertex_queue.erase(vertex_queue.begin());
// Visit each edge exiting u
const std::vector<neighbor> &neighbors = adj_list[u.id_stop];
for(std::vector<neighbor>::const_iterator neighbor_iter = neighbors.begin();
neighbor_iter != neighbors.end();
neighbor_iter++)
{
stop v = neighbor_iter->target;
int weight = neighbor_iter->weight;
int distance_through_u = dist + weight;
if (distance_through_u < min_distance[v.id_stop]) {
vertex_queue.erase(std::make_pair(min_distance[v.id_stop], v));
min_distance[v.id_stop] = distance_through_u;
previous[v.id_stop] = u;
vertex_queue.insert(std::make_pair(min_distance[v.id_stop], v));
}
}
if(u.id_stop == dst.id_stop)
{
std::cout << "Find : ";
for ( ; dst != fake_stop; dst = previous[dst.id_stop])
{
path.push_front(dst);
}
return path;
}
}
}
int main()
{
std::vector< std::vector<neighbor> > adj_list(9);
stop stop_s;
stop_s.id_stop = 1001;
stop_s.name_stop = "A";
stop stop_x;
stop_x.id_stop = 1002;
stop_x.name_stop = "B";
adj_list[stop_s.id_stop].push_back(neighbor(stop_x, 5));
stop_s.id_stop = 1003;
stop_s.name_stop = "C";
adj_list[stop_x.id_stop].push_back(neighbor(stop_s, 15));
stop_x.id_stop = 1004;
stop_x.name_stop = "D";
adj_list[stop_s.id_stop].push_back(neighbor(stop_x, 20));
stop_s.id_stop = 1001;
stop_s.name_stop = "A";
std::vector<int> min_distance;
std::vector<stop> previous;
std::list<stop> path = dijkstraComputeAndGetShortestPaths(stop_s, stop_x, adj_list, min_distance, previous);
std::cout << "Distance from 1001 to 1004: " << min_distance[stop_x.id_stop] << std::endl;
//std::cout << "Path : ";
#if 0
for (int index = 0; index < path.size(); index++)
{
auto path_front = path.begin();
std::advance(path_front, index);
std::cout << path_front->id_stop << " ";
}
std::cout << std::endl;
#endif
return 0;
}
std::set require you to specify an operator < for the type it holds or you can supply your own comparison functor as a template parameter. Since stop does not have an operator < the operator < from std::pair is not compileable since it relies on using the operator < of the types it holds.. You either need to supply your own comparison functor or define an operator < for stop.

error deleting item from list after passing through function

I'm having a bit of trouble understanding what's happening when I try to delete an element from a list in this program i'm working on.
#include <cmath>
#include <cstdio>
#include <list>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int findHigherSkillLevel(int skillLevel, list<int>::iterator *it, list<int> &list) {
if (it == NULL) return 0;
if (**it == (skillLevel + 1)) {
it = list.erase(it);
return 1 + findHigherSkillLevel(**it, it, list) + findHigherSkillLevel(**it, --it, list);
}
return 0;
}
int findLowerSkillLevel(int skillLevel, list<int>::iterator *it, list<int> &list) {
if (it == NULL) return 0;
if (**it == (skillLevel - 1)) {
it = list.erase(it);
return 1 + findLowerSkillLevel(**it, it, list) + findLowerSkillLevel(**it, --it, list);
}
return 0;
}
int findGroupsSizes(int skillLevel, list<int>::iterator *it, list<int> &list) {
if (it == NULL) return 0;
int groupSize = 1;
it = list.erase(it);
groupSize += findHigherSkillLevel(**it, it, list) + findLowerSkillLevel(**it, it, list);
return groupSize;
}
int main() {
int t; // the number of test cases
cin >> t;
vector<list<int> > skillLevels(t, list<int>());
// input for each test case
for (int i = 0; i < t; i++) {
int n; // number of students for this test case
cin >> n;
// initialize the list for this test case
for (int j = 0; j < n; j++) {
int skillLevel;
cin >> skillLevel;
skillLevels[i].push_back(skillLevel);
}
}
// recursively scan lists for smallest teams
for (int i = 0; i < t; i++) {
int minGroupNumber = skillLevels[i].size();
list<int>::iterator iterator = skillLevels[i].begin();
int skillLevel = skillLevels[i].front();
while (!skillLevels[i].empty()) {
int currentGroupSize = findGroupsSizes(skillLevel, &iterator, skillLevels[i]);
if (currentGroupSize < minGroupNumber)
minGroupNumber = currentGroupSize;
skillLevels[i].pop_front();
}
cout << minGroupNumber << endl;
}
return 0;
}
I already know that what's causing the error trying to call the "erase" function like this:
it = list.erase(it);
Which I typed in bold in the code. I don't understand why it's giving me the following output, since from what I understand erase() just needs an iterator to the location of the list to be deleted?:
teamFormation.cpp: In function ‘int findHigherSkillLevel(int, std::list<int>::iterator*, std::list<int>&)’:
teamFormation.cpp:13:24: error: no matching function for call to ‘std::list<int>::erase(std::list<int>::iterator*&)’
it = *list.erase(it);
^
teamFormation.cpp:13:24: note: candidates are:
In file included from /usr/include/c++/4.8/list:64:0,
from teamFormation.cpp:3:
/usr/include/c++/4.8/bits/list.tcc:108:5: note: std::list<_Tp, _Alloc>::iterator std::list<_Tp, _Alloc>::erase(std::list<_Tp, _Alloc>::iterator) [with _Tp = int; _Alloc = std::allocator<int>; std::list<_Tp, _Alloc>::iterator = std::_List_iterator<int>]
list<_Tp, _Alloc>::
^
/usr/include/c++/4.8/bits/list.tcc:108:5: note: no known conversion for argument 1 from ‘std::list<int>::iterator* {aka std::_List_iterator<int>*}’ to ‘std::list<int>::iterator {aka std::_List_iterator<int>}’
In file included from /usr/include/c++/4.8/list:63:0,
from teamFormation.cpp:3:
/usr/include/c++/4.8/bits/stl_list.h:1193:7: note: std::list<_Tp, _Alloc>::iterator std::list<_Tp, _Alloc>::erase(std::list<_Tp, _Alloc>::iterator, std::list<_Tp, _Alloc>::iterator) [with _Tp = int; _Alloc = std::allocator<int>; std::list<_Tp, _Alloc>::iterator = std::_List_iterator<int>]
erase(iterator __first, iterator __last)
^
/usr/include/c++/4.8/bits/stl_list.h:1193:7: note: candidate expects 2 arguments, 1 provided
teamFormation.cpp: In function ‘int findLowerSkillLevel(int, std::list<int>::iterator*, std::list<int>&)’:
teamFormation.cpp:24:24: error: no matching function for call to ‘std::list<int>::erase(std::list<int>::iterator*&)’
it = *list.erase(it);
^
teamFormation.cpp:24:24: note: candidates are:
In file included from /usr/include/c++/4.8/list:64:0,
from teamFormation.cpp:3:
/usr/include/c++/4.8/bits/list.tcc:108:5: note: std::list<_Tp, _Alloc>::iterator std::list<_Tp, _Alloc>::erase(std::list<_Tp, _Alloc>::iterator) [with _Tp = int; _Alloc = std::allocator<int>; std::list<_Tp, _Alloc>::iterator = std::_List_iterator<int>]
list<_Tp, _Alloc>::
^
/usr/include/c++/4.8/bits/list.tcc:108:5: note: no known conversion for argument 1 from ‘std::list<int>::iterator* {aka std::_List_iterator<int>*}’ to ‘std::list<int>::iterator {aka std::_List_iterator<int>}’
In file included from /usr/include/c++/4.8/list:63:0,
from teamFormation.cpp:3:
/usr/include/c++/4.8/bits/stl_list.h:1193:7: note: std::list<_Tp, _Alloc>::iterator std::list<_Tp, _Alloc>::erase(std::list<_Tp, _Alloc>::iterator, std::list<_Tp, _Alloc>::iterator) [with _Tp = int; _Alloc = std::allocator<int>; std::list<_Tp, _Alloc>::iterator = std::_List_iterator<int>]
erase(iterator __first, iterator __last)
^
/usr/include/c++/4.8/bits/stl_list.h:1193:7: note: candidate expects 2 arguments, 1 provided
teamFormation.cpp: In function ‘int findGroupsSizes(int, std::list<int>::iterator*, std::list<int>&)’:
teamFormation.cpp:35:22: error: no matching function for call to ‘std::list<int>::erase(std::list<int>::iterator*&)’
it = *list.erase(it);
^
teamFormation.cpp:35:22: note: candidates are:
In file included from /usr/include/c++/4.8/list:64:0,
from teamFormation.cpp:3:
/usr/include/c++/4.8/bits/list.tcc:108:5: note: std::list<_Tp, _Alloc>::iterator std::list<_Tp, _Alloc>::erase(std::list<_Tp, _Alloc>::iterator) [with _Tp = int; _Alloc = std::allocator<int>; std::list<_Tp, _Alloc>::iterator = std::_List_iterator<int>]
list<_Tp, _Alloc>::
^
/usr/include/c++/4.8/bits/list.tcc:108:5: note: no known conversion for argument 1 from ‘std::list<int>::iterator* {aka std::_List_iterator<int>*}’ to ‘std::list<int>::iterator {aka std::_List_iterator<int>}’
In file included from /usr/include/c++/4.8/list:63:0,
from teamFormation.cpp:3:
/usr/include/c++/4.8/bits/stl_list.h:1193:7: note: std::list<_Tp, _Alloc>::iterator std::list<_Tp, _Alloc>::erase(std::list<_Tp, _Alloc>::iterator, std::list<_Tp, _Alloc>::iterator) [with _Tp = int; _Alloc = std::allocator<int>; std::list<_Tp, _Alloc>::iterator = std::_List_iterator<int>]
erase(iterator __first, iterator __last)
^
/usr/include/c++/4.8/bits/stl_list.h:1193:7: note: candidate expects 2 arguments, 1 provided
The error message is self-explanatory: at that point it is not a std::list::iterator, it's actually an std::list::iterator*. You must dereference the pointer (as you did just on the previous line).

error printing element values of map

map<char, int> counter;
//some code...
map<char, int>::iterator iter;
for (i = 0; i<26; i++)
{
for (iter = counter[i].begin(); iter != counter[i].end(); iter++) //error occurs
{
cout << (*iter).first << " - " << (*iter).second << endl;
}
}
I'm not sure what this error message means:
*error: request for member âbeginâ in âcounter.std::map<_Key, _Tp , _Compare, _Alloc>::operator[] [with _Key = char, _Tp = int, _Compare = std::less, _Alloc = std::allocator >, std::map<_Key, __Tp, _Compare, _Alloc>::mapped_type = int, std::map<_Key, _Tp, _Compare, _Alloc>::key_type = char]((* &((std::map::key_type)j)))â, which is of non-class* *type âstd::map::mapped_type {aka int}â*
counter is a map not an array of map, one for loop from begin() to end() is enough, change your for loop to below code.
map<char, int> counter;
//some code...
for (map<char, int>::iterator iter = counter.begin(); iter != counter[i].end(); ++iter)
{
cout << (*iter).first << " - " << (*iter).second << endl;
}