By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,852 Members | 2,219 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,852 IT Pros & Developers. It's quick & easy.

std::map -- Function Objects??

P: n/a
Hi,

I'm confused about what the comparison operator in a map template is:

In particular, I want to know why something like the following doesn't
work:

bool pointCompare(POINT p1, POINT p2) {
if (p1.y > p2.y || (p1.y == p2.y && p1.x > p2.x) )
return true;
return false;
}

int main() {
std::map<POINT,bool,pointCompare> myMap;
return 0;
}

That code won't compile, because pointCompare is not a valid
comparison operator. Below is code that does work -- it creates a
class and then defines the function operator on it. I'm unclear as to
why that method works while the one above does not.

Also, in the line:

bool operator() (const string& s1, const string& s2) const {

what is the final "const" doing there?

Thanks for any clarification,
cpp

-----WORKING CODE FOLLOWS-----

#include <iostream>
#include <iomanip>
#include <map>
#include <string>
#include <algorithm>
using namespace std;

/* function object to compare strings
* - allows you to set the comparison criterion at runtime
* - allows you to compare case insensitive
*/
class RuntimeStringCmp {
public:
// constants for the comparison criterion
enum cmp_mode {normal, nocase};
private:
// actual comparison mode
const cmp_mode mode;

// auxiliary function to compare case insensitive
static bool nocase_compare (char c1, char c2)
{
return toupper(c1) < toupper(c2);
}

public:
// constructor: initializes the comparison criterion
RuntimeStringCmp (cmp_mode m=normal) : mode(m) {
}

// the comparison
bool operator() (const string& s1, const string& s2) const {
if (mode == normal) {
return s1<s2;
}
else {
return lexicographical_compare (s1.begin(), s1.end(),
s2.begin(), s2.end(),
nocase_compare);
}
}
};

/* container type:
* - map with
* - string keys
* - string values
* - the special comparison object type
*/
typedef map<string,string,RuntimeStringCmp> StringStringMap;

Jul 22 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
cppaddict wrote:
Hi,

I'm confused about what the comparison operator in a map template is:

In particular, I want to know why something like the following doesn't
work:

bool pointCompare(POINT p1, POINT p2) {
if (p1.y > p2.y || (p1.y == p2.y && p1.x > p2.x) )
return true;
return false;
}

int main() {
std::map<POINT,bool,pointCompare> myMap;
return 0;


Hi, you could just define the < for your class POINT ( you better call
it Point ) and declare the map:

std::map <Point> myMap;

class Point
{
//....
bool operator < ( Point p2 )
{
return (y > p2.y || (y == p2.y && x > p2.x);
}
}
Jul 22 '05 #2

P: n/a
cppaddict wrote:
Hi,

I'm confused about what the comparison operator in a map template is:

In particular, I want to know why something like the following doesn't
work:

bool pointCompare(POINT p1, POINT p2) {
if (p1.y > p2.y || (p1.y == p2.y && p1.x > p2.x) )
return true;
return false;
}

int main() {
std::map<POINT,bool,pointCompare> myMap;
return 0;
}

That code won't compile, because pointCompare is not a valid
comparison operator. Below is code that does work -- it creates a
class and then defines the function operator on it. I'm unclear as to
why that method works while the one above does not.
The map expects a type as 3rd template parameter, not a pointer to
function.
Also, in the line:

bool operator() (const string& s1, const string& s2) const {

what is the final "const" doing there?


It says that the operator won't change the function object.

Btw, you mustn't change the comparison function during the life time of
a map.

Jul 22 '05 #3

P: n/a
The map expects a type as 3rd template parameter, not a pointer to
function.


So what is the minimum implementation you'd have to give the function
object? Would it be:

class RuntimeStringCmp {
// the comparison
bool operator() (const string& s1, const string& s2) const {
if (mode == normal) {
return s1<s2;
}
else {
return lexicographical_compare (s1.begin(), s1.end(),
s2.begin(), s2.end(),
nocase_compare);
}
}
};

Thanks,
cpp
Jul 22 '05 #4

P: n/a
cppaddict wrote in news:vh********************************@4ax.com in
comp.lang.c++:
I'm confused about what the comparison operator in a map template is:

In particular, I want to know why something like the following doesn't
work:

bool pointCompare(POINT p1, POINT p2) {
if (p1.y > p2.y || (p1.y == p2.y && p1.x > p2.x) )
return true;
return false;
}

int main() {
std::map<POINT,bool,pointCompare> myMap;
return 0;
}

That code won't compile, because pointCompare is not a valid
comparison operator.


The Compare paramiter to std::map<> is a type, this needs to be a functor
or a function-pointer type, *not* a function.

Example that works, note the typedef comp_t and the arguments passed to
map's constructor:

#include <iostream>
#include <map>

bool fless( int const &left, int const &right )
{
return left < right;
}

bool fgreater( int const &left, int const &right )
{
return right < left;
}

typedef bool (*comp_t)( int const &, int const & );

int main()
{
using namespace std;

map< int, int, comp_t > lmap( fless ), gmap( fgreater );

for ( int i = 0; i < 10; ++i )
{
lmap[i] = gmap[i] = i * i;
}

map< int, int, comp_t >::iterator ptr, lim;

cout << "less:\n";
for ( ptr = lmap.begin(), lim = lmap.end(); ptr != lim; ++ptr )
{
cout << ptr->first << " - " << ptr->second << "\n";
}

cout << "\ngreater:\n";
for ( ptr = gmap.begin(), lim = gmap.end(); ptr != lim; ++ptr )
{
cout << ptr->first << " - " << ptr->second << "\n";
}
}

HTH.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #5

P: n/a
cppaddict wrote:
...
I'm confused about what the comparison operator in a map template is:

In particular, I want to know why something like the following doesn't
work:

bool pointCompare(POINT p1, POINT p2) {
if (p1.y > p2.y || (p1.y == p2.y && p1.x > p2.x) )
return true;
return false;
}

int main() {
std::map<POINT,bool,pointCompare> myMap;
return 0;
}

That code won't compile, because pointCompare is not a valid
comparison operator.


If you want to use a function pointer as a custom comparator for
'std::map', you have to declare and initialize your map as follows

std::map<POINT, bool, bool(*)(POINT, POINT)> myMap(pointCompare);

The third template parameter is the _type_ of the comparator, not the
actual instance. If you need to pass an instance of comparator to
'std::map', you have to pass it through constructor parameters.

--
Best regards,
Andrey Tarasevich

Jul 22 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.