5

独自のタイプのunordered_setをメンバーとして持つクラスを作成しています。したがって、のスペシャライゼーションを作成する必要がありhash<Foo>ます。この特殊化は、Fooが宣言された後に定義する必要があります。hash<Foo>しかし、メンバーを定義する前に、すでに専門化が必要であるように思えunordered_set<Foo>ます。少なくとも、コンパイルされず、そこで失敗します。ハッシュテンプレートの前方宣言を試みましたが、それでも機能させることができませんでした。

関連するコードスニペットは次のとおりです。

class Foo {
public:
    int i;
    std::unordered_set<Foo> dummy;
    Peer(std::unordered_set<Foo>);
};

namespace std {
    template<> struct hash<Foo>
    {
        size_t operator()(const Foo& f) const
        {
            return hash<int>()(f.i);
        }
    };
}

前もって感謝します

4

2 に答える 2

8

Fooタイプのメンバー変数を持つことはできませんstd::unordered_set<Foo>

不完全なタイプの標準ライブラリコンテナをインスタンス化することはできません。基本的に、ここでは関係のないいくつかの例外を除いて、クラスタイプは}その定義を終了するまで完全ではありません。

他のタイプをコンテナに格納するか(おそらくstd::unique_ptr<Foo>)、不完全なタイプでインスタンス化可能なコンテナを提供するコンテナライブラリを使用する必要があります(たとえば、Boostにはそのようなコンテナライブラリがあります)。

于 2012-01-08T22:24:22.050 に答える
1

宣言を少し動かしてコンパイルすることができます。

class Foo;

namespace std {
  template<> struct hash<Foo> {
    size_t operator()(const Foo& f) const;
  };
}

class Foo {
public:
  int i;
  std::unordered_set<Foo> dummy;
  Foo(std::unordered_set<Foo>);
};

namespace std {
  size_t hash<Foo>::operator()(const Foo& f) const {
    return hash<int>()(f.i);
  }
}

ただし、Jamesが言うように、isの宣言dummyは未定義の動作です。

また、同等性の比較も必要になります。に追加するのが最も簡単operator==ですFoo

Fooまた、const-referenceによって引数を取るのコンストラクターを作成することをお勧めします。

于 2012-01-08T22:26:18.177 に答える