size_t:运算符? (以及使用 unordered_set 的方法)

发布于 2024-11-18 22:39:28 字数 1818 浏览 2 评论 0原文

什么是

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来说,这似乎是equalshashCode,需要根据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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

陌路终见情 2024-11-25 22:39:28

它是类型转换运算符。基本上提供了将对象隐式转换为指定类型的功能,在本例中为size_t

编辑:

假设您有一个定义如下的函数:

void Foo( size_t x )
{
  // do something with x
}

如果您的类edge定义了用于转换为size_t的类型转换运算符,您可以执行以下操作如下:

edge e;
Foo( e );

编译器会自动将edge对象转换为size_t。正如 @litb 在评论部分所说,不要这样做。隐式转换可能会导致问题,因为它允许编译器在您不希望发生的情况下执行转换。

您应该定义一个像edge::to_size_t() 这样的成员函数(我知道这是一个糟糕的名字)来执行转换。

例如,std::string 定义了 std::string::c_str() 成员函数,而不是定义用于转换为 const 的类型转换运算符字符*。

编辑2:
抱歉,我没有仔细阅读你的问题。现在我看到您正在尝试在 std::unordered_set 中使用您的类。在这种情况下,您应该定义为您的类执行哈希和比较操作的函子。或者,您可以为您的类提供 std::hashstd::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:

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.

生生漫 2024-11-25 22:39:28

它是一个转换运算符,如错误 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 into size_t in this case. In general, operator X() {...} specifies how to create a X from your type.

宣告ˉ结束 2024-11-25 22:39:28

什么是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.

情深缘浅 2024-11-25 22:39:28

在任何类 Foo 中,operator T () const 都是一个强制转换运算符,它允许您将 Foo 强制转换为 T

Foo x;
T y = x; // invokes Foo::operator T() const

例如,std::fstream 有一个强制转换为布尔运算符,因此您可以在 if (mystream) ... 这样的表达式中使用它代码>.


为了满足您使用无序容器的需要:您将需要实现一个与签名 size_t (const Foo &) 匹配的哈希函数或函数对象。如果您想对用户代码影响最小,请专门化 std::hash

size_t my_magic_hash(const Foo &); // defined somehow
namespace std {
  template <>
  struct hash<Foo> : public std::unary_function<const Foo &, std::size_t>
  {
    inline std::size_t operator()(const Foo & x) const
    {
      return my_magic_hash(x);
    }
  };
}

现在我们可以直接使用 std::unordered_set ,前提是 Foo 提供 operator==

In any class Foo, operator T () const is a cast operator which lets you cast Foo to T:

Foo x;
T y = x; // invokes Foo::operator T() const

For example, an std::fstream has a cast-to-bool operator so you can use it in expressions like if (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, specialize std::hash<Foo>:

size_t my_magic_hash(const Foo &); // defined somehow
namespace std {
  template <>
  struct hash<Foo> : public std::unary_function<const Foo &, std::size_t>
  {
    inline std::size_t operator()(const Foo & x) const
    {
      return my_magic_hash(x);
    }
  };
}

Now we can use std::unordered_set<Foo> directly, provided Foo provides operator==.

童话里做英雄 2024-11-25 22:39:28

这是一个隐式转换运算符。它基本上允许您的类的对象在需要 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 as operator 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文