我正在将 C++ 程序从使用 Visual C++ 2008 构建的 Windows 转换为使用 gcc 4.6.1 在 Linux 上构建。有一个模块使用<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
未定义。我不确定当我做正确的tr1
包含时 VC++ 是否会发生这种情况——也许它会抱怨同样的事情?我明天试试,但现在我只有一个带有 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>'