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

Get a C++ set to contain objects

P: n/a
Hi!

I'm a Java guy, forced to do some C++. I want to add objects to the set
container. I don't even get past the compilation step (which is a good
thing in a way). For instance, why doesn't the following code compile?

#include <iostream>
#include <set>

using namespace std;

class myClass {
public:
void hello() { cout << "hello"; }
};

int main() {
myClass mc;

set<myClasss;
s.insert(mc); // If this line is commented away, no error
}
The compiles gives as a reason the following:

bikCC -o prog4 prog4.cc
"/opt/SUNWspro/prod/include/CC/Cstd/./functional", line 166: Error: The
operation "const myClass<const myClass" is illegal.
"/opt/SUNWspro/prod/include/CC/Cstd/rw/tree.cc", line 177: Where:
While instantiating "std::less<myClass>::operator()(const myClass&,
const myClass&) const".
"/opt/SUNWspro/prod/include/CC/Cstd/rw/tree.cc", line 177: Where:
Instantiated from __rwstd::__rb_tree<myClass, myClass,
__rwstd::__ident<myClass, myClass>, std::less<myClass>,
std::allocator<myClass>>::insert(const myClass&).
"/opt/SUNWspro/prod/include/CC/Cstd/./set", line 224: Where:
Instantiated from non-template code.
1 Error(s) detected.

Sep 30 '06 #1
Share this Question
Share on Google+
5 Replies


P: n/a
ja****@gmail.com wrote:
int main() {
myClass mc;

set<myClasss;
s.insert(mc); // If this line is commented away, no error
}
std::set is ordered, then it needs a way to compare things (and also to
evaluate equality). You need a < operator for objects of your class, or an
specialization for him of the std::less template, or add to the definition
of your set a compare operation.

--
Salu2
Sep 30 '06 #2

P: n/a
ja****@gmail.com wrote:
Hi!

I'm a Java guy, forced to do some C++. I want to add objects to the set
container. I don't even get past the compilation step (which is a good
thing in a way). For instance, why doesn't the following code compile?

#include <iostream>
#include <set>

using namespace std;

class myClass {
public:
void hello() { cout << "hello"; }
};

int main() {
myClass mc;

set<myClasss;
s.insert(mc); // If this line is commented away, no error
}
[snip]

The std::set<container keeps its elements in order. For this to happen,
you need to supply a comparison predicate. Technically, you have the
following options:

a) Define an operator< for myClass. This can be either a member operator or
a freestanding friend. This solution conveys the message that the objects
of type myClass a naturally comparable.

b) Specialize std::less<myClass>. This indicates that the ordering you
define is less natural and more of a hack to make things like std::set and
std::map work.

c) Define a freestanding comparison function

bool some_function_name ( myClass const &, myClass const & );

and pass it as a parameter upon construction of the set. Generally, I would
not recommend this since you will have to supply additional template
parameters and it makes the code less readable. This, I would use only when
there are several sorting criteria for the same type that I need to use
independently in the code.
In any case, the comparison predicate you supply has to define a ordering,
i.e., you may not have things like a < b < c < a and you should have either
a<b or b<a or a==b. If these conditions are not met, the code is likely to
compiler but it is also likely to give unexpected results (aka bugs).
Best

Kai-Uwe Bux
Sep 30 '06 #3

P: n/a
ja****@gmail.com wrote:
Hi!

I'm a Java guy, forced to do some C++. I want to add objects to the set
container. I don't even get past the compilation step (which is a good
thing in a way). For instance, why doesn't the following code compile?

#include <iostream>
#include <set>

using namespace std;

class myClass {
public:
void hello() { cout << "hello"; }
};

int main() {
myClass mc;

set<myClasss;
s.insert(mc); // If this line is commented away, no error
}
Note, although the above compiles in Java, it wouldn't work because the
set (TreeMap in Java) has no way to compare two myClass objects to see
what the order should be.
The compiles gives as a reason the following:

bikCC -o prog4 prog4.cc
"/opt/SUNWspro/prod/include/CC/Cstd/./functional", line 166: Error: The
operation "const myClass<const myClass" is illegal.
"/opt/SUNWspro/prod/include/CC/Cstd/rw/tree.cc", line 177: Where:
While instantiating "std::less<myClass>::operator()(const myClass&,
const myClass&) const".
The above complains about the very thing that would cause this code to
fail in Java. No way to compare two myClass objects to determine order.

To do that in C++, you must provide a global function that returns true
of the left hand argument comes before the right hand argument.

bool compare( const myClass& lhs, const myClass& rhs ) {
// return true if lhs should come before rhs, otherwise return false.
}

If you name your compare function "operator<" then the set will just
work. If you want to name it something else, then you will need to let
set know.

--
There are two things that simply cannot be doubted, logic and perception.
Doubt those, and you no longer*have anyone to discuss your doubts with,
nor any ability to discuss them.
Sep 30 '06 #4

P: n/a

ja****@gmail.com wrote:
Hi!

I'm a Java guy, forced to do some C++. I want to add objects to the set
container. I don't even get past the compilation step (which is a good
thing in a way). For instance, why doesn't the following code compile?

#include <iostream>
#include <set>

using namespace std;

class myClass {
public:
void hello() { cout << "hello"; }
};

int main() {
myClass mc;

set<myClasss;
s.insert(mc); // If this line is commented away, no error
}
The compiles gives as a reason the following:

bikCC -o prog4 prog4.cc
"/opt/SUNWspro/prod/include/CC/Cstd/./functional", line 166: Error: The
operation "const myClass<const myClass" is illegal.
"/opt/SUNWspro/prod/include/CC/Cstd/rw/tree.cc", line 177: Where:
While instantiating "std::less<myClass>::operator()(const myClass&,
const myClass&) const".
"/opt/SUNWspro/prod/include/CC/Cstd/rw/tree.cc", line 177: Where:
Instantiated from __rwstd::__rb_tree<myClass, myClass,
__rwstd::__ident<myClass, myClass>, std::less<myClass>,
std::allocator<myClass>>::insert(const myClass&).
"/opt/SUNWspro/prod/include/CC/Cstd/./set", line 224: Where:
Instantiated from non-template code.
1 Error(s) detected.
You must overload myClass's operator <
Like this:

#include <iostream>
#include <set>
using namespace std;
class myClass {
public:
myClass():data(0){}
void hello() { cout << "hello"; }
bool operator<(const myClass& rhs) const
{
return data<rhs.data;
}
private:
int data;//This is a comparative data.
};
int main() {
myClass mc;

set<myClasss;
s.insert(mc); // If this line is commented away, no error

}

Sep 30 '06 #5

P: n/a
"Daniel T." <da******@earthlink.netwrote in message
news:da****************************@news.west.eart hlink.net...
ja****@gmail.com wrote:
>Hi!

I'm a Java guy, forced to do some C++. I want to add objects to the set
container. I don't even get past the compilation step (which is a good
thing in a way). For instance, why doesn't the following code compile?

#include <iostream>
#include <set>

using namespace std;

class myClass {
public:
void hello() { cout << "hello"; }
};

int main() {
myClass mc;

set<myClasss;
s.insert(mc); // If this line is commented away, no error
}

Note, although the above compiles in Java, it wouldn't work because the
set (TreeMap in Java) has no way to compare two myClass objects to see
what the order should be.
TreeSet surely?

<snip>
Oct 1 '06 #6

This discussion thread is closed

Replies have been disabled for this discussion.