6

什么是

operator size_t () const

环境:Visual Studio 2010 Professional


TL; 博士

今天我正在寻找一种使用std::tr1::unordered_set. 因为上次问了怎么用,所以决定自己去查一下。std::map

我用谷歌搜索,大部分结果告诉我有一个结构来做散列。这条路对我来说看起来有点复杂,我一直在寻找,终于找到了另一种方法。

我需要实施

bool operator == (const edge & another) const

operator size_t () const

生成的代码接近问题的结尾。

==熟悉没有任何问题。size_t也很熟悉。但什么是operator size_t

似乎equalshashCodeJava 一样,需要根据 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
4

5 回答 5

14

它是类型转换运算符。基本上提供了将对象隐式转换为指定类型,在这种情况下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 char *.

编辑2: 对不起,我没有仔细阅读你的问题。现在我看到您正在尝试在std::unordered_set. 在这种情况下,您应该为您的类定义执行散列和比较操作的函子。或者,您可以为您的类提供模板特化std::hashstd::equal_to而不必在创建unordered_set对象时指定可选模板参数。

正如您在问题中所问的那样,这非常类似于 Java 的hashCode()成员函数,但是由于 C++ 类并非都从 Java 类等公共基类派生,因此它不是作为可覆盖的基类函数实现的。

于 2011-07-05T15:25:30.847 回答
2

它是一个转换运算符,如error C2549: user-defined conversion cannot specify a return type. size_t它定义了在这种情况下如何将您的类型转换为。通常,operator X() {...}指定如何X从您的类型创建一个。

于 2011-07-05T15:25:30.860 回答
2

是什么operator size_t () const

这是一个转换函数。它是一个函数,允许您将类的对象隐式转换为 type size_t。在我提供的链接中查看更多信息和示例。嗯。

于 2011-07-05T15:26:05.367 回答
1

在任何类Foo中,operator T () const都有一个强制转换运算符,可让您强制Foo转换为T

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

例如, anstd::fstream有一个 cast-to-bool 运算符,因此您可以在诸如if (mystream) ....


为了满足您使用无序容器的需求:您将需要实现与签名匹配的哈希函数或函数对象size_t (const Foo &)。如果您想对用户代码的影响最小,请专门化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);
    }
  };
}

现在我们可以std::unordered_set<Foo>直接使用了,提供Foooperator==.

于 2011-07-05T15:25:27.457 回答
1

这是一个隐式转换运算符。size_t它基本上允许在预期a 的上下文中使用您的类的对象(调用该运算符进行转换)。

为了使用unordered_set需要有某种 hashign 函数。在这种情况下,它被伪装成operator size_t,我并不真正推荐它,因为它只是混淆了它是一个哈希函数的事实。我会继续定义一个真正的哈希函数/函子并使用它。它会更清楚,未来的维护者会感谢你。

于 2011-07-05T15:45:50.147 回答