是unordered_set <reference_wrapper <ty>&gt;有效?</的reference_wrapper <TY>

时间:2012-08-11 15:59:24

标签: c++ reference c++11 hashset

这是有效的C ++(考虑到最新标准)吗?我在Ubuntu 12.04上使用near-of-tree-clang / libc ++获得编译错误。如果它应该有效,我会将clang-dev列表与错误消息等邮寄。

#include <functional>
#include <unordered_set>

struct X
{
    int i; 
};

void f ()
{
    std::unordered_set<std::reference_wrapper<X>> setOfReferencesToX;

    // Do stuff with setOfReferencesToX
}

**顺便说一句,我已经厌倦了这个问题/答案是针对最新标准的。作为一个整体的C ++社区,请开始限定旧标准特有的东西吗?新标准已经推出了大约一年了。

1 个答案:

答案 0 :(得分:8)

问题并非针对std::reference_wrapper<T>,而是针对X类型本身。

问题是std::unordered_set要求您为std::reference_wrapper<X>定义散列和平等函子。您可以将散列函数作为第二个模板参数传递。

例如,这可行:

#include <functional> // for std::hash<int>

struct HashX {
  size_t operator()(const X& x) const {
    return std::hash<int>()(x.i);      
  }
};

然后

std::unordered_set<std::reference_wrapper<X>, HashX> setOfReferencesToX;

另一个选择是为std::hash<X>

进行专业化
namespace std {
template <>
struct hash<X> {
  size_t operator()(const X& x) const {
    return std::hash<int>()(x.i);      
  }
};
}

这允许您避免显式指定第二个模板参数:

std::unordered_set<std::reference_wrapper<X>> setOfReferencesToX;

关于相等比较,您可以通过为类X提供相等运算符来解决此问题:

struct X
{
  bool operator==(const X& rhs) const { return i == rhs.i; }
  int i; 
};

否则,您可以定义自己的仿函数并将其作为第三个模板参数传递。