457,911 Members | 1,147 Online Need help? Post your question and get tips & solutions from a community of 457,911 IT Pros & Developers. It's quick & easy.

# map with pair of key

 P: n/a Hello! I would like to use the map structure with a key of Pair and an int as the value. Pair is defined as: template class Pair { public: T1 first; T2 second; Pair() { } Pair(T1 first, T2 second) { this->first = first; this->second = second; } virtual ~Pair() { } bool operator == (const Pair p) const { return (first == p.first && second == p.second) || (first == p.second && second == p.first); } bool operator < (const Pair p) const { return !(*this == p) && (first < p.first || (!(p.first < first) && second < p.second)); } }; That means the two pairs of, for instance, strings ("A", "B") and ("B", "A") are equals. Unfortunately, when I run the following code, I have a strange behaviour. map, int> myMap; bonds[Pair("A", "B")] = 1; bonds[Pair("A", "C")] = 2; bonds[Pair("A", "D")] = 3; bonds[Pair("A", "E")] = 4; bonds[Pair("A", "F")] = 5; cout << myMap[Pair("A", "B")] << "\n"; cout << myMap[Pair("B", "A")] << "\n"; cout << myMap[Pair("A", "C")] << "\n"; cout << myMap[Pair("C", "A")] << "\n"; cout << myMap[Pair("A", "D")] << "\n"; cout << myMap[Pair("D", "A")] << "\n"; cout << myMap[Pair("A", "E")] << "\n"; cout << myMap[Pair("E", "A")] << "\n"; cout << myMap[Pair("A", "F")] << "\n"; cout << myMap[Pair("F", "A")] << "\n"; The outputs are: 1 0 2 2 3 0 4 4 5 0 It should not contain 0! but I should have twice the same number like: 1 1 2 2 3 3 4 4 5 5 Why is it not as expected? Does anyone know what I'm doing wrong? Thank you in advance, John May 10 '06 #1
4 Replies

 P: n/a Florent Garcin wrote: Hello! I would like to use the map structure with a key of Pair and an int as the value. Didn't this come up a few days ago? Pair is defined as: template class Pair { public: T1 first; T2 second; Pair() { } Pair(T1 first, T2 second) { this->first = first; this->second = second; Use initialiser lists. } virtual ~Pair() { } bool operator == (const Pair p) const Use const Pair& { return (first == p.first && second == p.second) || (first == p.second && second == p.first); } bool operator < (const Pair p) const Use const Pair& { return !(*this == p) && (first < p.first || (!(p.first < first) && second < p.second)); } }; That means the two pairs of, for instance, strings ("A", "B") and ("B", "A") are equals. Where are your tests for the above assertion? Add some and you should find your problem. -- Ian Collins. May 10 '06 #2

 P: n/a "Florent Garcin" wrote in message news:11************@sicinfo3.epfl.ch... : I would like to use the map structure with a key of Pair : and an int as the value. : : Pair is defined as: .... : bool operator < (const Pair p) const : { : return !(*this == p) && (first < p.first || (!(p.first < first) && : second < p.second)); : } .... : That means the two pairs of, for instance, strings ("A", "B") and ("B", : "A") are equals. Well, this is not what your operator < implies: as it looks through map elements using a bunary search based on op<, the functions of std::map will be taken away from the entry being looked for. But does it make sense for your pair class to accept separate types for its two elements if the elements are supposed to be interchangeable ?? I don't think so. : Unfortunately, when I run the following code, I have a strange behaviour. .... : Why is it not as expected? Does anyone know what I'm doing wrong? When std::map does not behave as expected, always check your ordering function. If you want the order of the pair's element no not matter, try something like: friend bool operator < ( .... a, .... b ) { T const* a1 = &a.first; T const* a2 = &a.second; if( *a2<*a1 ) swap( a1, a2 ); T const* b1 = &b.first; T const* b2 = &b.second; if( *b2<*b1 ) swap( b1, b2 ); return (*a1<*b1)||(!(*b1<*a1)&&(*a2<*b2); } Or possibly better & easier: keep the two elements of your pair class ordered at all times ( e.g. swap first & second if the latter is smaller ). Amicalement --Ivan -- http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form May 10 '06 #3

 P: n/a Ian Collins wrote: Florent Garcin wrote:Hello!I would like to use the map structure with a key of Pairand an int as the value. Didn't this come up a few days ago? yeah, you are right! Pair is defined as:template class Pair{public: T1 first; T2 second; Pair() { } Pair(T1 first, T2 second) { this->first = first; this->second = second; Use initialiser lists. what do you mean? } virtual ~Pair() { } bool operator == (const Pair p) const Use const Pair& { return (first == p.first && second == p.second) || (first == p.second&& second == p.first); } bool operator < (const Pair p) const Use const Pair& { return !(*this == p) && (first < p.first || (!(p.first < first) &&second < p.second)); }};That means the two pairs of, for instance, strings ("A", "B") and ("B","A") are equals. Where are your tests for the above assertion? Add some and you should find your problem. May 10 '06 #4

 P: n/a John schrieb: Pair is defined as: template class Pair { public: T1 first; T2 second; Pair() { } Pair(T1 first, T2 second) { this->first = first; this->second = second; Use initialiser lists. what do you mean? Pair(T1 first_, T2 second_) : first(first_), second(second_) { } /S -- Stefan Naewe naewe.s_AT_atlas_DOT_de May 10 '06 #5

### This discussion thread is closed

Replies have been disabled for this discussion. 