View Full Version : C++: map with custom compare
erotavlas
July 19th, 2013, 04:04 PM
#include <iostream>
#include <map>
class MapCompare { // a more complicated comparison function which varies according to specified parameter s
public:
MapCompare(const int size_) : size(size_) {};
bool operator()(const int* x,const int* y)
{
for(int i = 0; i < size; i++)
{
if(x[i] < y[i])
{
return true;
}
else if(x[i] > y[i])
{
return false;
}
return true; // if they are equal
}
}
private:
int size;
};
int main ()
{
static int N=4;
int array1[N];
int array2[N];
int * array1_ptr=array1;
int * array2_ptr=array2;
for (int i = 0; i < N; i++)
{
array1_ptr[i] = 2;
array2_ptr[i] = 3;
}
for (int i = 0; i < N; i++)
{
std::cout << array1_ptr[i] << " ";
}
std::map<int*, int, MapCompare> myMap(MapCompare(N));
myMap[array1_ptr] = 3;
myMap[array2_ptr] = 4;
for(std::map<int*, int, MapCompare>::const_iterator it = myMap.begin(); it != myMap.end(); it++)
{
std::cout << "my map " << it->second << std::endl;
}
return 0;
}
MG&TL
July 19th, 2013, 04:39 PM
What's your question? If you're just showing some code, cool, but you might want to say as much.
erotavlas
July 19th, 2013, 04:52 PM
My code does not compile:
code.c:51:19: error: invalid types ‘std::map<int*, int, MapCompare>(MapCompare)[int*]’ for array subscript
code.c:53:20: error: invalid types ‘std::map<int*, int, MapCompare>(MapCompare)[int*]’ for array subscript
code.c:55:67: error: request for member ‘begin’ in ‘myMap’, which is of non-class type ‘std::map<int*, int, MapCompare>(MapCompare)’
code.c:55:88: error: request for member ‘end’ in ‘myMap’, which is of non-class type ‘std::map<int*, int, MapCompare>(MapCompare)’
Where us the error?
GeneralZod
July 19th, 2013, 05:56 PM
Please use code tags!
The error is in the line:
std::map<int*, int, MapCompare> myMap(MapCompare(N));
Google for "most vexing parse".
Edit:
Also, install clang and try compiling with clang++ for a further hint :)
erotavlas
July 19th, 2013, 06:23 PM
Ok, thank you. Now the comparator works.
I have updated my code. I cannot understand why if I try to find inside the map I don't find anything. The map contains as key the address of the array.
#include <iostream>
#include <map>
class MapCompare { // a more complicated comparison function which varies according to specified parameter s
public:
MapCompare(const int size_) : size(size_) {};
bool operator()(const int* x,const int* y)
{
for(int i = 0; i < size; i++)
{
if(x[i] < y[i])
{
return true;
}
else if(x[i] > y[i])
{
return false;
}
return true; // if they are equal
}
}
private:
int size;
};
int main ()
{
static int N=4;
int array1[N];
int array2[N];
int * array1_ptr=array1;
int * array2_ptr=array2;
for (int i = 0; i < N; i++)
{
array1_ptr[i] = 2;
array2_ptr[i] = 2;
array1_ptr[0] = 1;
array2_ptr[0] = 3;
array2_ptr[N-1] = 1;
}
for (int i = 0; i < N; i++)
{
std::cout << array1_ptr[i] << " ";
}
std::cout << std::endl;
for (int i = 0; i < N; i++)
{
std::cout << array2_ptr[i] << " ";
}
std::cout << std::endl;
std::map<int*, int, MapCompare> myMap((MapCompare(N)));
myMap[array1_ptr] = 3;
myMap[array2_ptr] = 4;
for(std::map<int*, int, MapCompare>::const_iterator it = myMap.begin(); it != myMap.end(); it++)
{
std::cout << "my map " << it->first << " " << it->second << std::endl;
}
std::map<int*, int, MapCompare>::const_iterator it = myMap.find(array2_ptr);
if(it != myMap.end())
{
std::cout << "my map " << it->first << " " << it->second << std::endl;
}
else
std::cout << "not found" << std::endl;
return 0;
}
GeneralZod
July 19th, 2013, 06:32 PM
In your "for" loop, you only ever compare one pair of elements.
Edit:
Also, read this: you are disobeying the contract.
http://www.cplusplus.com/reference/map/map/key_comp/
erotavlas
July 20th, 2013, 08:43 AM
Of course, I want to compare less pairs as possible to speed up the key comparison. It seems that the error was in the return value when the elements are equal.
class MapCompare { // a more complicated comparison function which varies according to specified parameter s
public:
MapCompare(const int size_) : size(size_) {};
bool operator()(const int* x,const int* y)
{
for(int i = 0; i < size; i++)
{
if(x[i] < y[i])
{
return true;
}
else if(x[i] > y[i])
{
return false;
}
}
return false; // if they are equal -> The error
}
private:
int size;
};
Thank you for your help.
erotavlas
July 20th, 2013, 09:38 AM
My final question. It is legal to declare a class that contains a map with custom compare like this?
class MyClass {
public:
MyClass(const int N_):N(N_){
myMap.clear();
};
private:
int N;
typedef std::map<unsigned int*, int, MapCompare> MyMap;
MyMap myMap(MapCompare(N));
};
};
I get the following error:
In constructor ‘MyClass::MyClass(int)’:
error: ‘((MyClass*)this)->MyClass::myMap’ does not have class type
GeneralZod
July 20th, 2013, 11:33 AM
class MyClass {
public:
MyClass(const int N_):N(N_), myMap(MapCompare(N)) {
myMap.clear();
};
private:
int N;
typedef std::map<unsigned int*, int, MapCompare> MyMap;
MyMap myMap;
};
Powered by vBulletin® Version 4.2.2 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.