Best way to organize my sorting funtcors?

S

Steve555

Hi,

I've ended up with many, many operator< functors like this

bool operator<(UserRating lhs, UserRating rhs) {
return lhs.userID < rhs.userID;
}

to sort the many custom structs I have, and the typedefined vectors I
have to store them.
All of the structs and their vectors are neatly organized in to one
myVecDefiness.h file, but the functors are dotted about all over the
place. If I try to put them in myVecDefiness.h (or any other header),
then the compiler complains of multiple definitions (even though I
have #ifndef etc. in the header). But if I put them in a single .cpp
then the compiler doesn't find them.

What's the neatest way to organize this?

Thanks

Steve
 
K

Kai-Uwe Bux

Steve555 said:
Hi,

I've ended up with many, many operator< functors like this

bool operator<(UserRating lhs, UserRating rhs) {
return lhs.userID < rhs.userID;
}

to sort the many custom structs I have, and the typedefined vectors I
have to store them.
All of the structs and their vectors are neatly organized in to one
myVecDefiness.h file, but the functors are dotted about all over the
place. If I try to put them in myVecDefiness.h (or any other header),
then the compiler complains of multiple definitions (even though I
have #ifndef etc. in the header). But if I put them in a single .cpp
then the compiler doesn't find them.

What's the neatest way to organize this?

The comparison above is a free-standing function, but nonetheless part of
the public interface of UserRating. I would put its declaration with the
declaration of that struct and its implementation with the implementation
of all other parts of the interface.

BTW: I would only overload operator< if it makes sense. Usually, a
well-named comparison function will be more clear (but has to be passed to
the algorithms explicitly).


Best

Kai-Uwe Bux
 
S

Steve555

The comparison above is a free-standing function, but nonetheless part of
the public interface of UserRating. I would put its declaration with the
declaration of that struct and its implementation with the implementation
of all other parts of the interface.

BTW: I would only overload operator< if it makes sense. Usually, a
well-named comparison function will be more clear (but has to be passed to
the algorithms explicitly).

Best

Kai-Uwe Bux

Thanks Kai, does that mean I should then find anywhere I've used
std::binary_search() etc. and manually add the "well-named comparison
function" as the last parameter?
 
Z

zr

Hi,

I've ended up with many, many  operator< functors like this

bool operator<(UserRating lhs, UserRating rhs) {
        return lhs.userID < rhs.userID;

}

to sort the many custom structs I have, and the typedefined vectors I
have to store them.
All of the structs and their vectors are neatly organized in to one
myVecDefiness.h file, but the functors are dotted about all over the
place. If I try to put them in myVecDefiness.h (or any other header),
then the compiler complains of multiple definitions (even though I
have #ifndef etc. in the header). But if I put them in a single .cpp
then the compiler doesn't find them.

What's the neatest way to organize this?

Thanks

Steve

Just a thought.
If all of your classes contain an ID field, you could consider
inheriting them all from a common base class that contains that field.
That way you will only need to define one comparison operator for the
base class.

class BaseClass
{
friend bool operator<(const BaseClass& a, const BaseClass& b);
//...
protected:
int id;
};

bool operator<(const BaseClass& a, const BaseClass& b)
{
return a.id < b.id;
}


class A : public BaseClass
{
//...
};

class B : public BaseClass
{
//...
};


Beware: this will allow comparisons between objects of different types
if their classes inherit from BaseClass:
A a;
B b;
a < b; //ok
 
S

Steve555

Just a thought.
If all of your classes contain an ID field, you could consider
inheriting them all from a common base class that contains that field.
That way you will only need to define one comparison operator for the
base class.

class BaseClass
{
        friend bool operator<(const BaseClass& a, const BaseClass& b);
//...
protected:
        int id;

};

bool operator<(const BaseClass& a, const BaseClass& b)
{
        return a.id < b.id;

}

class A : public BaseClass
{
//...

};

class B : public BaseClass
{
//...

};

Beware: this will allow comparisons between objects of different types
if their classes inherit from BaseClass:
A a;
B b;
a < b; //ok

Thanks for the idea, that would clean things up a lot, but I'm not
sure if I can afford the over head of converting mu structs to classes
as I'm trying to fit millions in to limited memory. Any idea what the
cost of this would be on a typical struct that might contain two
shorts, one long, and a float?
 
S

Steve555

Try it.

--
  Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

It's not laziness honest! ;-)... but I have 20+ classes to write, as
well as the code that references them I'll rephrase the question: Is
there a way to calculate the size of one such class for comparison? I
thought the class itself with the minimum constructor etc. took up
some amount of bytes?
 
Z

zr

Thanks for the idea, that would clean things up a lot, but I'm not
sure if I can afford the over head of converting mu structs to classes
as I'm trying to fit millions in to limited memory. Any idea what the
cost of this would be on a typical struct that might contain two
shorts, one long, and a float?

See these topics:
http://www.parashift.com/c++-faq-lite/classes-and-objects.html#faq-7.8
http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.4
Bottom line: if you do not define any virtual method in your class,
the overhead is zero.
 
S

Steve555

See these topics:http://www.parashift.com/c++-faq-li.../c++-faq-lite/virtual-functions.html#faq-20.4
Bottom line: if you do not define any virtual method in your class,
the overhead is zero.

Yup, to quote from the first link:
"A class feels like a living and responsible member of society with
intelligent services, a strong encapsulation barrier, and a well
defined interface."
Exactly my mental block. I'm glad we got on this topic because I think
I'll be less hesitant about using classes in future.
 
J

joecook

Is
there a way to calculate the size of one such  class for comparison? I
thought the class itself with the minimum constructor etc. took up
some amount of bytes?

Nope, you are mistaken. For your purposes, 'class' and 'struct' are
totally synonymous, except one defaults to 'public' and one defaults
to 'private'. That's it.

Joe C
 
S

Steve555

Nope, you are mistaken.   For your purposes, 'class' and 'struct' are
totally synonymous, except one defaults to 'public' and one defaults
to 'private'.  That's it.

Joe C

Thanks Joe, it's an eye-opener.
 
S

Steve555

In a header file you should have:

inline bool operator<(const UserRating& lhs, const UserRating& rhs) {
     return lhs.userID < rhs.userID;

}

The inline keyword effectively tells the linker to not complain about
multiple definitions. However, operator< is maybe not the best naming, at
least I would expect that comparison of UserRating-s would be done by
some rating scores, not by user ID-s. Such discrepancies may cause
maintainability issues later.

hth
Paavo

Thanks for the inline info. I'm keeping different copies of vectors
sorted by different members for speed.
 
J

Juha Nieminen

Steve555 said:
If I try to put them in myVecDefiness.h (or any other header),
then the compiler complains of multiple definitions

That's precisely what the 'inline' keyword is for. Put it in front of
the function definitions and the compiler won't complain anymore.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top