Visual C++ 2008 を使用した Windows ビルドから gcc 4.6.1 を使用した Linux でビルドする C++ プログラムを変換しています。を使用するモジュールがあります<unordered_map>
。VC++ では、完全に問題ないようです。
#include <unordered_map>
...
std::tr1::unordered_map<mystruct, int> my_map;
実際には、gcc 4.6 と VC++ 2008 だけでなく、より多くのコンパイラをサポートしているため、純粋な C++2011 コードを使用することは現実的ではありません。gcc は に腹を#include <unordered_map>
立て、これは真の c++2011 インクルード ファイルであると不平を言います。
#include <tr1/unordered_map>
...
std::tr1::unordered_map<mystruct, int> my_map;
これは機能します。けっこうだ。しかし、今私は別の問題を抱えています。mystruct の定義は次のとおりです。
struct mystruct
{
#ifdef __cplusplus
inline operator size_t() const
{
return m_val;
}
#endif
unsigned int m_val;
};
VC++ 2008 では、これstd::hash
はmystruct
. std::tr1::hash
一方、少なくともgcc 4.6.1では、これは好きではありません。std::tr1::hash<mystruct>::operator()( mystruct ) const
未定義であると不平を言って、リンクを拒否します。適切なインクルードを行ったときに VC++ でそれが発生するかどうかはわかりませtr1
ん - おそらく同じことについて文句を言うでしょうか? 明日試してみますが、今のところ、gcc を搭載した Linux ボックスしかありません。今のところ、私はそれを機能させるためにこれをしなければなりませんでした:
namespace std {
namespace tr1 {
std::size_t hash<mystruct>::operator()( mystruct & c ) const
{
return c.m_val;
}
}
}
これがどのように機能するかについて誰かが教えてくれますか? size_t
ハッシュ可能にしたい型に演算子を定義できる方がはるかにエレガントに思えますが、私はoperator()
onを定義して喜んで生きstd::tr1::hash
ます。
アップデート:
提案されているように、ハッシュクラス全体を特殊化してみました。gccでビルドすると、
myfile.cpp:41:12: error: specialization of 'std::tr1::hash<mystruct>' after instantiation
myfile.cpp:41:12: error: redefinition of 'struct std::tr1::hash<mystruct>'
/usr/include/c++/4.6/tr1/functional_hash.h:45:12: error: previous definition of 'struct std::tr1::hash<mystruct>'