473,385 Members | 1,641 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Slight problem using user-defined types with STL sets

Hello all,

I've got a fairly basic question about STL sets and operator overloading
in general.

I'm working with a data type that's essentially a 2-element vector. A
simplified (hacked) version would be something like this:

struct twotuple
{
...

int x;
int y;
};
Now, what I want to be able to do is to use a set to take the union of a
whole bunch of vectors, so that similar vectors will only be stored once.
For instance:

----------------------
set<twotuple> s;

twotuple t1(1, 2);
twotuple t2(2, 1);
twotuple t3(1, 2);

s.insert(t1);
s.insert(t2);
s.insert(t3);
-----------------------

should result in there only being two vectors stored in s (namely, t1 and
t2). I'm under the impression that a set determines equality based on operator<;
I'm guessing that it does something like

if (!(a < b) && !(b<a))

to see if two user-defined structures are equal. My question is, how
should I overload operator< in this case for two-tuples? It seems obvious,
but you can't just ensure that the x and y of one tuple are both less than
the x and y of another tuple, because that will result in 'fake'
equalities in some cases (eg (1 2) and (2 1) will fulfill
!(a < b) && !(b < a) ).

I'm sorry if the answer to this is dead obvious and I'm just being dense.
Any help would be appreciated.

-Debo
Jul 22 '05 #1
3 1800

"Debo" <md******@NOSPAM.student.cs.uwaterloo.ca> wrote in message
news:Pi******************************@cpu14.studen t.cs.uwaterloo.ca...
Hello all,

I've got a fairly basic question about STL sets and operator overloading
in general.

I'm working with a data type that's essentially a 2-element vector. A
simplified (hacked) version would be something like this:

struct twotuple
{
...

int x;
int y;
};
Now, what I want to be able to do is to use a set to take the union of a
whole bunch of vectors, so that similar vectors will only be stored once.
For instance:

----------------------
set<twotuple> s;

twotuple t1(1, 2);
twotuple t2(2, 1);
twotuple t3(1, 2);

s.insert(t1);
s.insert(t2);
s.insert(t3);
-----------------------

should result in there only being two vectors stored in s (namely, t1 and
t2). I'm under the impression that a set determines equality based on operator<;

Actually it uses std::less<twotuple>, which delegates to operator<
I'm guessing that it does something like

if (!(a < b) && !(b<a))
This is the test for equivalence of keys.
to see if two user-defined structures are equal. My question is, how
should I overload operator< in this case for two-tuples? It seems obvious,
but you can't just ensure that the x and y of one tuple are both less than
the x and y of another tuple, because that will result in 'fake'
equalities in some cases (eg (1 2) and (2 1) will fulfill
!(a < b) && !(b < a) ).


Try a lexicographical ordering, e.g.

bool operator<(const twotuple& lhs, const twotuple& rhs)
{
return lhs.x < rhs.x ||
!rhs.x < lhs.x && lhs.y < rhs.y;
}

This says "lhs is less than rhs with respect to the first coordinate, or lhs and
rhs are equivalent with respect to the first coordinate but lhs is less than rhs
with respect to the second coordinate."

Jonathan
Jul 22 '05 #2


On Sun, 28 Nov 2004, Jonathan Turkanis wrote:

JT> Try a lexicographical ordering, e.g.
JT>
JT> bool operator<(const twotuple& lhs, const twotuple& rhs)
JT> {
JT> return lhs.x < rhs.x ||
JT> !rhs.x < lhs.x && lhs.y < rhs.y;
JT> }
JT>
JT> This says "lhs is less than rhs with respect to the first coordinate, or lhs and
JT> rhs are equivalent with respect to the first coordinate but lhs is less than rhs
JT> with respect to the second coordinate."
JT>
JT> Jonathan

That worked perfectly; thanks so much!

-Debo
Jul 22 '05 #3
Debo wrote:

On Sun, 28 Nov 2004, Jonathan Turkanis wrote:

JT> Try a lexicographical ordering, e.g.
JT>
JT> bool operator<(const twotuple& lhs, const twotuple& rhs)
JT> {
JT> return lhs.x < rhs.x ||
JT> !rhs.x < lhs.x && lhs.y < rhs.y;
JT> }
JT>
JT> This says "lhs is less than rhs with respect to the first coordinate, or lhs and
JT> rhs are equivalent with respect to the first coordinate but lhs is less than rhs
JT> with respect to the second coordinate."
JT>
JT> Jonathan

That worked perfectly; thanks so much!

-Debo


Hm. I'd prefer to write this something like this:

class my_vec
{
public:
class special_order;
friend class my_vec::special_order;

my_vec( int x_, int y_ )
: x( x_ ), y( y_ )
{}

class special_order
{
public:
bool operator()( const my_vec& a, const my_vec& b )
{
// just use std::pair's implementation of
// "operator <" to define or "lexical" order...
return
std::make_pair( a.x, a.y ) <
std::make_pair( b.x, b.y );
}
};

protected:
int x;
int y;
};

void something()
{
std::set<my_vec, my_vec::special_order> my_set;

my_set.insert( my_vec( 1, 1 ) );
my_set.insert( my_vec( 1, 2 ) );
my_set.insert( my_vec( 2, 1 ) );
my_set.insert( my_vec( 1, 1 ) );
assert( my_set.size() == 3 );
}

Works perfectly well too :-)
The reasons why I'd prefer that way are not easy to explain, but I'd not
define an "operator <" just to have a std::set function - unless I
need that "operator <" and it's semantics are natural and clear I'd just
not do it...
Bye, monster
Jul 22 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Thomas Womack | last post by:
I'm using the csv module in python 2.3 under Windows XP; it seems that two separate mechanisms try to handle the perverse Windows habit of ending lines with 0d0a, and so writer =...
3
by: Ivan Van Laningham | last post by:
Hi All-- I noticed recently that a few of the jpgs from my digital cameras have developed bitrot. Not a real problem, because the cameras are CD Mavicas, and I can simply copy the original from...
13
by: Deano | last post by:
Hi, I generate a report using two dates (From and To). I notice if I enter 01/10/2003 that it is interpreted by Access as 10/01/2003 i.e 10th January rather than 1st October as I intended. ...
2
by: JNY | last post by:
Hello, I've searched for a solution, but can't find one. When adding two numbers I'm not getting the expected result: int testInt = 3056; float testMant = 0.9001; float testTotal; ...
5
by: Brian | last post by:
Hello all.. Am working on an Air Hockey game... have an table loaded into a picture box. The borders of the table are slightly slanted. Am using hit testing lines with GDI+ to manipulate the...
17
by: Rob Meade | last post by:
Hi all, I have written a small windows service which checks a directory for a new file, upon receiving one writes a line to the log file and then copies the file to SQL server. I've had a few...
4
by: Adam Maltby | last post by:
Hi, I need to do a transparent label but with a difference. I have drawn on my form a custom background using CreateGraphics as I needed an ellipse looking fill in a rectangle - so the actual...
0
by: Billie Boy | last post by:
Hi to all. I’m new here and am coming to you from Melbourne Australia. So a big HELLO 2 ALL. Thanx for having me here. TOP forum you guy's have here! Can anyone answer my problem? Please. ...
1
by: chris | last post by:
I have a form that is labeled Document Control. On this form it calls an API Function to browse for a folder, puts its in to the text box and allows you to create a table out of the folders...
2
by: nicola | last post by:
hello, I need a simple and slight forum write in c# exume me, for the ot, but I'm desperated
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.