【问题标题】:Syntax to pass argument to unordered_set hash function in c++在 C++ 中将参数传递给 unordered_set 哈希函数的语法
【发布时间】:2017-01-13 19:18:56
【问题描述】:

我为我正在使用的自定义类型创建了一个哈希类,但它有一个带参数的构造函数。我无法弄清楚在 unordered_set 中使用它的语法。

class Hasher {
    unsigned arg;
public:
    Hasher(unsigned a) : arg(a) {}
    size_t operator()(const MyType& t) const {
        return calculate_hash(arg, t);
    }
}

int main() {
    unordered_set<MyType, Hasher(2)> myset; // compilation error
}

错误信息:

In file included from Tetrahedron.cc:5:
./Triangulation.h:52:29: error: template argument for template type parameter must be a type
       unordered_set<TetraFace,FaceHasher(2)> faces2;
                               ^~~~~~~~~~~~~
/bin/../lib/gcc/x86_64-redhat-linux/6.3.1/../../../../include/c++/6.3.1/bits/unordered_set.h:90:11: note: template parameter is declared here
       class _Hash = hash<_Value>,
             ^

我也试过

unordered_set<MyType, Hasher> myset(Hasher(2));

但我仍然收到错误:

In file included from Tetrahedron.cc:5:
./Triangulation.h:52:59: error: expected ')'
    unordered_set<TetraFace,FaceHasher> faces2(FaceHasher(2));
                                                          ^
./Triangulation.h:52:58: note: to match this '('
unordered_set<TetraFace,FaceHasher> faces2(FaceHasher(2));
                                                     ^

【问题讨论】:

    标签: c++ syntax clang++ unordered-set


    【解决方案1】:

    因为您试图将 Hasher 类型的对象(即实例)作为模板参数传递,所以您在此处遇到编译错误。

    就像你的错误描述的那样:template argument for template type parameter must be a type

    它需要一个类型,而你正在传递一个值。

    在类型级别参数化 arg。

    template<unsigned A>
    class Hasher {
        unsigned arg = A;
    public:
        size_t operator()(const int& t) const {
            std::cout << arg << std::endl;
            return 0;
        }
    };
    
    int main() {
        std::unordered_set<int, Hasher<2>> myset;
        myset.insert(5); // prints 2
    
        std::unordered_set<int, Hasher<3>> myset2;
        myset2.insert(3); // prints 3
    }
    

    【讨论】:

      【解决方案2】:

      不幸的是,仅使用哈希对象无法构造std::unorderd_set。采用哈希对象的All of the constructors 在其前面有一个参数为bucket_count。您需要为它指定值

      unordered_set<MyType, Hasher> myset(some_bucket_count_value, Hasher(2));
      

      如果您不想这样做,那么您必须使 Hasher 默认可构造。

      也不是这样

      return calculate_hash(arg);
      

      不管你通过什么MyType,你总是会散列arg,这是行不通的。您需要对 MyType 对象进行哈希处理,std::unordered_set 才能真正起作用。

      【讨论】:

      • 是的,calculate_hash 只是一个例子,表明我需要使用 arg。只是为了确定一下,您说的是 unordered_map,但 unordered_set 也是如此,对吧?
      • 另外,如果我指定了一个初始桶数,C++ 是否会在必要时处理更改它,还是我自己也必须这样做?
      • @devil0150 哎呀。 set 也是如此。刚刚更新了答案。
      • 桶数只是桶的最小数量。如果需要,它会做得更多。
      猜你喜欢
      • 1970-01-01
      • 2013-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-23
      • 2017-07-22
      • 2023-03-28
      • 1970-01-01
      相关资源
      最近更新 更多