9

这是有效的 C++(考虑到最新标准)吗?我在 Ubuntu 12.04 上使用接近树顶的 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++ 社区是否可以开始限定特定于旧标准的东西?较新的标准已经发布了大约一年。

4

1 回答 1

9

问题不是特定于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;

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

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

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

于 2012-08-11T16:02:36.137 回答