Reputation: 11247
EDIT after answered:
<
should be provided for std::map
. For more information about best practice, go for James McNellis's answer.
The code included in this question is poorly written. It is just because I am playing with SPOJ and the input data is strictly valid. The std::string
approach is what I chose at first, but it turned out to be not fast enough.
Thank you.
I know I cannot use char[]
directly with map, such as map<char[], int>
. Thus I put it in a class. But it still can go through compilation. How to deal with that?
#include <stdio.h>
#include <map>
using namespace std;
class id {
public:
char v [30];
};
int main () {
map<id, int> m;
id a;
while (gets(a.v)) {
m[a]++;
}
return 0;
}
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = id]’:
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_map.h:418: instantiated from ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = id, _Tp = int, _Compare = std::less<id>, _Alloc = std::allocator<std::pair<const id, int> >]’
prog.cpp:15: instantiated from here
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_function.h:230: error: no match for ‘operator<’ in ‘__x < __y’
It seems it has something to do with comparison, but I am still in the dark.
Upvotes: 1
Views: 390
Reputation: 355039
First things first: never, ever use gets
. It cannot be used safely and any program that uses it has a security vulnerability. There is no way to limit the number of characters that gets
can write to the buffer that you provide it, so there is no way to prevent a buffer overflow. If you do need to use the C I/O library, you should use fgets
instead, which allows you to specify the maximum number of characters to be read.
The reason that you are seeing this error is that the key type that you use must be comparable somehow. By default std::map
uses operator<
, which you do not define for id
, hence the compilation error. You either need to define operator<
to compare two id
objects or you need to write a comparator functor that can be used to compare the two objects. Regardless which you choose, the comparator must provide a strict-weak ordering.
Since you are programming in C++, the ideal solution here is to use idiomatic C++:
std::map<std::string, int> m;
std::string s;
while (std::cin >> s) {
m[s]++;
}
std::string
already provides operator<
that provides a lexicographic ordering, so you don't need to define a comparator yourself.
Upvotes: 6
Reputation: 54600
In order to insert into the map, the map needs to be able to compare id's. You haven't provided an implementation of operator< that it can use. You have two options:
I think you should use std::string. You can use the .c_str() method to convert it to a char array when you need to.
Upvotes: 0
Reputation: 44093
You need to implement the <
operator
class id {
public:
char v [30];
bool operator<(const id &rhs) const{
return strcmp(v,rhs.v) < 0;
}
};
EDIT: As a side note your code is a very poor way of doing things. See some of the answers for an explanation why.
Upvotes: 3