6

とは

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ですか?

equals効果的hashCodeなJavaに従って一緒にオーバーライドする必要がある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::hashます。std::equal_tounordered_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。私が提供したリンクで詳細情報と例を参照してください。H番目。

于 2011-07-05T15:26:05.367 に答える
1

どのクラスFooでも、operator T () constは次のようにキャストできるキャスト演算子です。FooT

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

たとえば、 anstd::fstreamにはキャストからブール演算子があるため、 のような式で使用できます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);
    }
  };
}

これで、提供されたprovidesをstd::unordered_set<Foo>直接使用できます。Foooperator==

于 2011-07-05T15:25:27.457 に答える
1

これは暗黙の変換演算子です。基本的に、クラスのオブジェクトを asize_tが期待されるコンテキストで使用できるようにします (その演算子を呼び出して変換を行います)。

使用unordered_setするには、ある種のハッシュ関数が必要です。この場合、 に偽装されてoperator size_tいますが、ハッシュ関数であるという事実を単に難読化しているだけなので、あまりお勧めしません。先に進んで、実際のハッシュ関数/ファンクターを定義し、代わりにそれを使用します。それはより明確になり、将来のメンテナはあなたに感謝します.

于 2011-07-05T15:45:50.147 に答える