size_t:运算符? (以及使用 unordered_set 的方法)
什么是
operator size_t () const
环境:Visual Studio 2010 Professional
TL; DR
今天我正在寻找一种使用 std::tr1::unordered_set 的方法。因为我询问如何使用std::map
上次,我决定自己找出来。
我用谷歌搜索,大多数结果告诉我有一个结构来进行散列。这条路对我来说有点复杂,我不断寻找,终于找到了另一种方法。
我需要实现
bool operator == (const edge & another) const
并且
operator size_t () const
生成的代码接近问题的结尾。
==
很熟悉,没有任何问题。 size_t
也很熟悉。但是什么是operator size_t
?
对于Java来说,这似乎是equals
和hashCode
,需要根据Effective Java一起重写。但我不确定,尤其是当名称为 size_t
时。
结果代码如下。完整的程序运行良好,并产生正确的输出。
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;
}
};
再多一点:
不是
size_t operator () const
不能编译:
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
即使不能,
int operator size_t () const
但据我所知,该函数返回int
。错误代码如下:
error C2549: user-defined conversion cannot specify a return type
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
它是类型转换运算符。基本上提供了将对象隐式转换为指定类型的功能,在本例中为
size_t
。编辑:
假设您有一个定义如下的函数:
如果您的类
edge
定义了用于转换为size_t
的类型转换运算符,您可以执行以下操作如下:编译器会自动将
edge
对象转换为size_t
。正如 @litb 在评论部分所说,不要这样做。隐式转换可能会导致问题,因为它允许编译器在您不希望发生的情况下执行转换。您应该定义一个像edge::to_size_t() 这样的成员函数(我知道这是一个糟糕的名字)来执行转换。
例如,
std::string
定义了std::string::c_str()
成员函数,而不是定义用于转换为const 的类型转换运算符字符*。
编辑2:
抱歉,我没有仔细阅读你的问题。现在我看到您正在尝试在
std::unordered_set
中使用您的类。在这种情况下,您应该定义为您的类执行哈希和比较操作的函子。或者,您可以为您的类提供std::hash
和std::equal_to
模板特化,而不必在创建unordered_set 时指定可选模板参数对象。
正如您在问题中所问的那样,这非常类似于 Java 的
hashCode()
成员函数,但由于 C++ 类并不都像 Java 类一样派生自公共基类,因此它不会实现为可重写的基类函数。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:
If your class
edge
defines the type-cast operator for conversion tosize_t
you can do the following:The compiler will automatically convert the
edge
object tosize_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 thestd::string::c_str()
member function instead of defining the type-cast operator for conversion toconst 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 ofstd::hash
andstd::equal_to
for your class and not have to specify the optional template parameters when creating theunordered_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.它是一个转换运算符,如
错误 C2549:用户定义的转换无法指定返回类型
所示。在这种情况下,它定义了如何将您的类型转换为size_t
。一般来说,operator X() {...}
指定如何从您的类型创建X
。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 intosize_t
in this case. In general,operator X() {...}
specifies how to create aX
from your type.什么是
operator size_t () const
?这是一个转换函数。该函数允许您隐式将类的对象转换为
size_t
类型。请参阅我提供的链接中的更多信息和示例。哈。What is
operator size_t () const
?It's a conversion-function. It's a function that allows you to implicitly convert an object of your class to type
size_t
. See further info and examples in the link I provided. Hth.在任何类
Foo
中,operator T () const
都是一个强制转换运算符,它允许您将Foo
强制转换为T
:例如,
std::fstream
有一个强制转换为布尔运算符,因此您可以在if (mystream) ...
这样的表达式中使用它代码>.为了满足您使用无序容器的需要:您将需要实现一个与签名
size_t (const Foo &)
匹配的哈希函数或函数对象。如果您想对用户代码影响最小,请专门化std::hash
:现在我们可以直接使用
std::unordered_set
,前提是Foo
提供operator==
。In any class
Foo
,operator T () const
is a cast operator which lets you castFoo
toT
:For example, an
std::fstream
has a cast-to-bool operator so you can use it in expressions likeif (mystream) ...
.In response to your need to use unordered containers: You will need to implement a hash function or function object, which matches the signature
size_t (const Foo &)
. If you want to do it with least visible impact on the user code, specializestd::hash<Foo>
:Now we can use
std::unordered_set<Foo>
directly, providedFoo
providesoperator==
.这是一个隐式转换运算符。它基本上允许您的类的对象在需要
size_t
的上下文中使用(调用该运算符来进行转换)。为了使用
unordered_set
,您需要拥有某种哈希函数。在这种情况下,它被伪装成operator size_t
,我真的不推荐这样做,因为它只是混淆了它是哈希函数的事实。我会继续定义一个真正的哈希函数/函子并使用它。它将更加清晰,未来的维护者会感谢你。That's an implicit conversion operator. It basically allows an object of your class to be used in a context where a
size_t
is expected (calling that operator to do the conversion).In order to use
unordered_set
you need to have some sort of hashign function. In this case, it's being disguised asoperator size_t
, which I don't really recommend because it's simply obfuscating the fact that it's a hash function. I would just go ahead and define a real hash function/functor and use that instead. It'll be more clear and future maintainers will thank you.