c ++ std :: tr1 :: hash :: operator()undefined?

时间:2012-05-07 05:53:30

标签: c++ visual-c++ gcc c++11 tr1

我正在使用Visual C ++ 2008将C ++程序从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更改为

#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()上定义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>'

2 个答案:

答案 0 :(得分:6)

Microsoft接受隐式转换为std::size_t的方式是一种扩展。

GCC的方式,专门化std::tr1::hash,是TR1实际定义的方式,现在已经在C ++ 11中标准化了(当然,tr1::部分被删除了。)

MSVC仍然应该接受hash专门化,当然两者都应该接受作为Hasher模板参数传递的全新类。

专门研究整个班级的风格更好,而不仅仅是operator()函数:

namespace std {
    namespace tr1 {
        template<>
        struct hash< mystruct > {
            std::size_t operator()( mystruct & c ) const 
            { 
                return c.m_val; 
            }
        };
    }
}

答案 1 :(得分:2)

由于您的mystruct是由用户定义的,因此您需要为unordered_map提供哈希函数:

struct my_hash {
std::size_t operator()( mystruct & c ) const 
        { 
            return c.m_val; 
        }
};

std::tr1::unordered_map<mystruct, int, my_hash> my_map;
相关问题