unordered_setでのハッシュ関数指定方法

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
chaemon

unordered_setでのハッシュ関数指定方法

#1

投稿記事 by chaemon » 14年前

C++0xのunordered_setに関する質問です。新たにMyDataという構造体を作り、それをキーとしたunordered_set<MyData>を構築したいのですが、どうしてもうまくいきません。
原因はhash関数の指定にあるようで、unordered_set<MyData, 以降の部分にhash_value関数を指定したいのですが、どのように指定したらよいのでしょうか。
よろしくお願いします。

ちなみに、用いているコンパイラは
g++ (Ubuntu 4.6.0-3~ppa1) 4.6.1 20110409 (prerelease)
で、
コンパイルの際にオプション
-std=gnu++0x
を付けています。

unordered_set<string>などは(別のハッシュ関数の指定方法はわかりませんが)正常に動作します。

コード:

#include<iostream>
#include<unordered_set>
using namespace std;

struct MyData{
	int x;

	bool operator==( const MyData& rhs ) const
	{
		return x==rhs.x;
	}
};

size_t hash_value( const MyData& d ){
	size_t h = 12345;
	return h;
}

int main()
{
	unordered_set<MyData> s;
	MyData d;
	d.x=3333;
	s.insert(d);
//	s.insert(d);
	cout << s.size() << endl;
}

アバター
うしお
記事: 56
登録日時: 14年前

Re: unordered_setでのハッシュ関数指定方法

#2

投稿記事 by うしお » 14年前

あまり詳しくなく、見つけられないだけなら申し訳ないのですが、tr1に独自型を入れるのは少し面倒なようですねー
ただboost::unordered_setならば提示されたソースでコンパイルは通ります。(まあ当然定数値を返すとただの線形リストになりますが)
これを期にboostをインストールしてみてはいかがでしょう?

たかぎ
記事: 328
登録日時: 14年前
住所: 大阪
連絡を取る:

Re: unordered_setでのハッシュ関数指定方法

#3

投稿記事 by たかぎ » 14年前

コード:

namespace std
{
    template <>
    struct hash<MyData>
    {
        size_t operator()(const MyData& d) const
        {
            return hash_value(d);
        }
    };
}
上記のコードを追加してみてください。

chaemon

Re: unordered_setでのハッシュ関数指定方法

#4

投稿記事 by chaemon » 14年前

ひとまず解決しました。ありがとうございます!boostも検討します!

しかしながら、たかぎさんがご投稿いただいたnamespaceで指定する方法ですと、ひとつのハッシュ関数しか指定できないように思えますが、複数の関数を使い分けたい場合はどのようにしたらいいのでしょうか?

やはり、うしおさんのおっしゃる通り、面倒なのでしょうか。。。

アバター
うしお
記事: 56
登録日時: 14年前

Re: unordered_setでのハッシュ関数指定方法

#5

投稿記事 by うしお » 14年前

いいえ、たかぎさんの方法で何種類でも追加が可能です。
これは見慣れない構文かもしれませんが、テンプレート特殊化といわれる機能です。
特にunordered_setが特別なわけではありません。
簡単にいうと「この型の時は特別にこっち使ってね」というような意味になります。
この方法を用いてもよいですし、インストールの手間こそかかりますが、boostを用いるのもよいと思います。

追記
「面倒」と表現したのは「作業量が多い」わけではありませんでした
少々混乱を招いてすみません。
・「知らない人には意味不明に見える構文が増える」のを避ける
・boostは他にも便利なものも数多くある
・インストールするだけで解決する
・見た目も分かりやすい
といったメリットを私は推したいと考えたためです。

chaemon

Re: unordered_setでのハッシュ関数指定方法

#6

投稿記事 by chaemon » 14年前

すみません。。。「ひとつしか指定できない」というのは自分の勘違いでした。
以下のようにやってみたらうまくできました!
最初、「namespace std{}」の中に構造体をもうひとつつくってそれを第二引数に指定するという無謀な(?)
ことをやってしまって失敗したので先のような投稿をしてしまいました。

ありがとうございました!

それにしても、テンプレート特殊化は知らなかったのですが、便利ですね!

コード:

#include<iostream>
#include<unordered_set>

using namespace std;

struct MyData{
	int x;
	bool operator==( const MyData& rhs ) const{
		return x==rhs.x;
	}
};

namespace std{
	template <>
		struct hash<MyData>{
			size_t operator()(const MyData& d) const{
				return 12345;
			}
		};
}

struct MyStruct{
	size_t operator()(const MyData& d) const {
		return 67890;
	}
};

int main(){
	//	unordered_set<MyData,hash<MyData> > s; 
	unordered_set<MyData,MyStruct > s;
	MyData d;
	d.x=3333;
	s.insert(d);
	cout << s.size() << endl;
}



chaemon

Re: unordered_setでのハッシュ関数指定方法

#7

投稿記事 by chaemon » 14年前

すみません。。。解決のチェックを忘れたので再度投稿します。

ありがとうございました!

ちなみに、もうひとつ懸案を抱えていて、それがどうやらテンプレート特殊化にまつわるものっぽいので、
もし自分で解決できなかったらまた投稿させていただきます。

そのときはよろしくお願いします。

閉鎖

“C言語何でも質問掲示板” へ戻る