Compiling error when insert pair into set [duplicate] - c++

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.

Related

Permutations of a string --error: no matching function for call to ‘std::set<char>::insert(std::string&)’

I am not a professional c++ programmer. I have tried to write a program to display all possible permutations of a given input string assuming if the string contains duplicate characters. This the code I have written so far:
Latest update of my code (permutation.cpp):
#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <list>
#include <set>
#include <iterator>
#include <sstream>
#include <cstdlib>
using namespace std;
//factorial function
int factorial(int n){
if (n==0) return 1;
else{
return n*factorial(n-1);
}
}
int main (int argc, char *argv[]) {
srand ( time(NULL) ); //initialize the random seed
char* text;
std::set<char> mySwapList;
if ( argc < 1 )
{
cout << endl << "Please write a word in the following of the command line" << endl << endl;
return 1;
}
else if ( argc != 2 ) // argc should be 2 for correct execution
{ // We print argv[0] assuming it is the program name
strcpy (text,argv[1]);
cout<<endl<<"usage: "<< argv[0] <<" to compute all the permutations \n"<<endl;
return 1;
}
int ss=sizeof(text);
int length = ss;
int k=0;
cout << "length of the word:"<<endl<< length<<endl;
int total=factorial(length);
while (k< total)
{
char arr[ss];
int index=0;
stringstream ssin(text);
while (ssin.good() && index<ss){
ssin>>arr[index];
++index;
}
std::list<char> word(arr, arr+ss);
std::list<char> mylist;
unsigned int j=0;
while (j < length)
{
int n=word.size();
int RandIndex = rand() % n;
std::list<char>::iterator vi= word.begin();
std::advance(vi,RandIndex);
std::list<char>::iterator iter= mylist.begin();
mylist.insert(iter,*vi);
word.remove(*vi);
j++;
}
char str[ss];
int ii=0;
for (std::list<char>::iterator ix=mylist.begin(); ix!=mylist.end(); ++ix)
{
str[ii]=*ix;
ii++;
}
string newWord = string(str);
for (std::set<char>::iterator iss=mySwapList.begin(); iss!=mySwapList.end(); ++iss)
{
string w(1,*iss);
if (newWord != w)
{
mySwapList.insert(newWord);
k++;
}
}
}
//Loop for printing the list
for(std::set<char>::iterator it = mySwapList.begin(); it != mySwapList.end(); ++it)
cout << *it << " ";
cout << endl;
return 0;
}
I get a a good deal of error messages when I compile the code, including:
Updated errors:
permutation.cpp: In function ‘int main(int, char**)’:
permutation.cpp:82:39: error: no matching function for call to ‘std::set<char>::insert(std::string&)’
mySwapList.insert(newWord);
^
permutation.cpp:82:39: note: candidates are:
In file included from /usr/include/c++/4.8/set:61:0,
from permutation.cpp:9:
/usr/include/c++/4.8/bits/stl_set.h:460:7: note: std::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 value_type&) [with _Key = char; _Compare = std::less<char>; _Alloc = std::allocator<char>; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator = std::_Rb_tree_const_iterator<char>; std::set<_Key, _Compare, _Alloc>::value_type = char]
insert(const value_type& __x)
^
/usr/include/c++/4.8/bits/stl_set.h:460:7: note: no known conversion for argument 1 from ‘std::string {aka std::basic_string<char>}’ to ‘const value_type& {aka const char&}’
/usr/include/c++/4.8/bits/stl_set.h:497:7: note: std::set<_Key, _Compare, _Alloc>::iterator std::set<_Key, _Compare, _Alloc>::insert(std::set<_Key, _Compare, _Alloc>::const_iterator, const value_type&) [with _Key = char; _Compare = std::less<char>; _Alloc = std::allocator<char>; std::set<_Key, _Compare, _Alloc>::iterator = std::_Rb_tree_const_iterator<char>; std::set<_Key, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<char>; std::set<_Key, _Compare, _Alloc>::value_type = char]
insert(const_iterator __position, const value_type& __x)
^
/usr/include/c++/4.8/bits/stl_set.h:497:7: note: candidate expects 2 arguments, 1 provided
/usr/include/c++/4.8/bits/stl_set.h:517:2: note: template<class _InputIterator> void std::set<_Key, _Compare, _Alloc>::insert(_InputIterator, _InputIterator) [with _InputIterator = _InputIterator; _Key = char; _Compare = std::less<char>; _Alloc = std::allocator<char>]
insert(_InputIterator __first, _InputIterator __last)
^
/usr/include/c++/4.8/bits/stl_set.h:517:2: note: template argument deduction/substitution failed:
permutation.cpp:82:39: note: candidate expects 2 arguments, 1 provided
mySwapList.insert(newWord);
I can not figure out why I got the above errors. Any suggestion?
Based on the question title you want to convert string to list.
You can't do it directly but you can use string iterator:
#include <string>
#include <list>
int main(int argc, _TCHAR* argv[])
{
std::string strTest = "hello!";
std::list<char> list(strTest.begin(), strTest.end());
return 0;
}
Edit: But based on your code you don't need list at all. You can use std::string everywhere. It has insert and [] stuff. It is almost the same as vector<char> but with additional functionality.
You used undefined class members.
Try strcpy_s() to char* arrays.
Using vector as a container for strings at the end of the code for mySwapList solves the problem of accepting strings as well as being easy to access each component of the vector. Here is the debugged and working version of the original question:
#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <list>
#include <set>
#include <iterator>
#include <sstream>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;
using std::vector;
//factorial function
int factorial(int n){
if (n==0) return 1;
else{
return n*factorial(n-1);
}
}
int main () {
srand ( time(NULL) ); //initialize the random seed
std::string text;
vector<std::string> mySwapList;
std::ostream_iterator<char> output(cout," ");
cout << endl << "Please write a word in the following of the command line" << endl << endl;
cin >>text;
int ss=text.size();
int k=0;
cout << "length of the word:" << endl << ss<<endl<<"input value:\n" <<text<< endl;
int total=factorial(ss);
cout << "The number of final permutations :\n"<<total<<endl;
while (k< total)
{
char arr[ss];
int index=0;
stringstream ssin(text);
while (ssin.good() && index<ss){
ssin>>arr[index];
++index;
}
std::list<char> word;
//insert items from arr into word list
word.insert(word.begin(),arr, arr+ss);
//A tool to print lists
cout<<"word contains:\n "<<endl;
std::copy(word.begin(),word.end(),output);
cout << endl;
std::list<char> mylist;
unsigned int j=0;
while (j < ss)
{
int n=word.size();
int RandIndex = rand() % n;
std::list<char>::iterator vi= word.begin();
std::advance(vi,RandIndex);
word.erase(vi);
std::list<char>::iterator iter= mylist.begin();
mylist.insert(iter,*vi);
j++;
}
cout << "constructed permuted word:"<<endl;
std::copy(mylist.begin(),mylist.end(),output);
cout << endl;
char str[ss];
str[ss]='\0';
int ii=0;
for (std::list<char>::iterator ix=mylist.begin(); ix!=mylist.end(); ++ix)
{
str[ii]=*ix;
ii++;
}
string newWord = string(str);
cout << "New Word :"<< endl << newWord <<" size of string:\n"<< (sizeof(str)/sizeof(*str)) << endl;
if (k==0)
{
mySwapList.push_back(newWord);
k++;
}
else
{
int flag=0;
for (int i=0;i<mySwapList.size();i++)
{
if (mySwapList[i]==newWord)
flag=1;
}
if (flag!=1)
{
mySwapList.push_back(newWord);
k++;
}
}
}
//Loop for printing the vector mySwapList
for(unsigned int i=0; i<mySwapList.size();i++)
cout << mySwapList[i] << " ";
cout << endl;
return 0;
}

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.

Implementing BFS using 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);
}

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

using find_if in set

In my main.cpp:
using namespace std;
#include <cstdlib>
#include <iostream>
#include <set>
#include <string>
#include <cstring>
#include <sstream>
#include <algorithm>
class findme
{
public:
bool operator()(const std::string& s) {
return s == "tom";
}
};
int main(int argc, char *argv[])
{
set<string> myset;
myset.insert("tom");
myset.insert("jerry");
cout << myset.size();
set<string>::iterator it;
if (find_if(myset.begin(), myset.end(), findme())) {
cout << "found tom \n";
}
return EXIT_SUCCESS;
}
when I compiled the program, it got an error:
Could not convert std::find_if [with _InputIterator = std::_Rb_tree_const_iterator<std::string>, _Predicate = findme]((&myset)->std::set<_Key, _Compare, _Alloc>::begin [with _Key = std::string, _Compare = std::less<std::string>, _Alloc = std::allocator<std::string>](), (&myset)->std::set<_Key, _Compare, _Alloc>::end [with _Key = std::string, _Compare = std::less<std::string>, _Alloc = std::allocator<std::string>](), (findme(), findme()))' to 'bool'
Can anyboy tell me where were I wrong? thank you
std::find_if returns an iterator to the found element (or one-past-the-end if no element matched the predicate):
std::set<std::string>::iterator it =
std::find_if(myset.begin(), myset.end(), findme());
if (it != myset.end())
{
// etc.