What is
operator size_t () const
Environment: Visual Studio 2010 Professional
TL; DR
Today I was searching for a way to use std::tr1::unordered_set
. Because I asked for how to use std::map
last time, I decided to find it out myself.
I googled and most of the results told me to have a struct to do hashing. The way looked a little bit complicated for me, and I kept searching and finally came across another approach.
I need to implement
bool operator == (const edge & another) const
and
operator size_t () const
The resulting code is near the end of the question.
==
is familiar without any problem. size_t
is familiar, too. But what is operator size_t
?
It seems like equals
and hashCode
for Java, which need to be overridden together according to Effective Java. But I am not sure, especially when the name is size_t
.
The resulting code is as follows. The complete program works fine, and produces correct outputs.
class edge {
public:
int x;
int y;
edge(int _x, int _y) : x(_x), y(_y) {
}
bool operator == (const edge & another) const {
return (x == another.x && y == another.y);
}
operator size_t () const {
return x * 31 + y;
}
};
A little bit more:
Not
size_t operator () const
which cannot be compiled:
error C2143: syntax error : missing ';' before 'const'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2059: syntax error : '{'
error C2334: unexpected token(s) preceding '{'; skipping apparent function body
Even not
int operator size_t () const
but as I see it, the function returns int
. The error code is as follows:
error C2549: user-defined conversion cannot specify a return type
It's the type cast operator. Basically provides for implicitly converting the object to the specified type, in this case size_t
.
EDIT:
Say you have a function defined as follows:
void Foo( size_t x )
{
// do something with x
}
If your class edge
defines the type-cast operator for conversion to size_t
you can do the following:
edge e;
Foo( e );
The compiler will automatically convert the edge
object to size_t
. As @litb says in the comments section, do not do this. Implicit conversions can cause trouble by allowing the compiler to perform conversions when you may not have intended for that to happen.
You should instead define a member function like edge::to_size_t()
(I know that's a terrible name) to perform the conversion.
As an example, std::string
defines the std::string::c_str()
member function instead of defining the type-cast operator for conversion to const char *
.
EDIT 2:
Sorry, I didn't read your question carefully enough. Now I see you're trying to use your class in an std::unordered_set
. In that case you should define functors that do the hash and compare operations for your class. Alternatively, you can provide template specializations of std::hash
and std::equal_to
for your class and not have to specify the optional template parameters when creating the unordered_set
object.
As you've asked in the question, this is very much like Java's hashCode()
member function, but since C++ classes do not all derive from a common base class like Java classes, it is not implemented as an override-able base class function.
It is a conversion operator, as hinted by error C2549: user-defined conversion cannot specify a return type
. It defines how your type can be converted into size_t
in this case. In general, operator X() {...}
specifies how to create a X
from your type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With