繁体   English   中英

c ++ 11多态映射键静态断言失败:哈希函数必须可通过键类型的参数调用

[英]c++11 polymorphic map keys static assertion failed: hash function must be invocable with an argument of key type

错误是

in file included from /usr/include/c++/8/unordered_map:46,
                from main.cpp:3:
/usr/include/c++/8/bits/hashtable.h: In instantiation of ‘class std::_Hashtable<MyClass*, std::pair<MyClass* const, double>, std::allocator<std::pair<MyClass* const, double> >, std::__detail::_Select1st, MyClassEquality, MyClassHash, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >’:
/usr/include/c++/8/bits/unordered_map.h:105:18:   required from ‘class std::unordered_map<MyClass*, double, MyClassHash, MyClassEquality>’
main.cpp:35:68:   required from here
/usr/include/c++/8/bits/hashtable.h:195:21: error: static assertion failed: hash function must be invocable with an argument of key type
    static_assert(__is_invocable<const _H1&, const _Key&>{},
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/8/bits/hashtable.h:197:21: error: static assertion failed: key equality predicate must be invocable with two arguments of key type
    static_assert(__is_invocable<const _Equal&, const _Key&, const _Key&>{},
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

该代码是

#include <iostream>
#include <functional>
#include <unordered_map>

using namespace std;

class MyClass {
public:
    long my_id;

    MyClass() {
        my_id = lrand48();
    }

    size_t id() const {
        hash<long> long_hash;
        return long_hash(my_id);
    }
};

struct MyClassHash {
public:
    size_t operator() (const MyClass * &c) const {
        return c->id();
    }
};

struct MyClassEquality {
public:
    bool operator() (const MyClass * &a, const MyClass * &b) const {
        return a->id() == b->id();
    }
};

class TestClass {
public:
    unordered_map<MyClass *, double, MyClassHash, MyClassEquality> my_map;;

/* makes no difference
 * TestClass() {
 *        my_map = unordered_map<MyClass *, double, MyClassHash, MyClassEquality>(42, MyClassHash(), MyClassEquality());
 *    }
 */

    void test() {
        for (auto p : my_map) {
            cout << p.first << "," << p.second << endl;
        }
    }
};

int main(int argc, char * argv[]) {
    auto * a = new TestClass();
    a->test();
    return 0;
}

映射将指针作为键的原因是,程序在与映射的内容进行交互时需要利用多态性。 代码中是否有相对简单的监督,还是有更合适的设计模式?

我试过的变化,如改变struct s到class上课,不声明该散列/平等运营商public ,等等; 类似地,注释的构造函数。

考虑到使用多态指针作为映射键的一般设计模式似乎没有什么特别有用的结果,我将正确地将修改后的代码发布为rafix07,并很快提出建议

struct MyClassHash {
public:
    size_t operator() (const MyClass * c) const {
        return c->id();
    }
};

struct MyClassEquality {
public:
    bool operator() (const MyClass * a, const MyClass * b) const {
        return a->id() == b->id();
    }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM