C++:如何制作由 std::function 索引的容器?

C++: How to make a container indexed by std::function?

对于索引,我使用 std::unordered_mapstd::map。它们都在使用时抛出编译错误如下:

std::unordered_map<std::function<bool(Ent*)>, int> var;

std::unordered_map 由于引用已删除的函数而失败

std::map 由于没有 < operator

而失败

对我来说理想的解决方案是使用一种类型的map,但如果必须使用另一种类型的容器,那应该不是问题

将函数作为容器键的一种方法是将它们包装到函子结构中

#include <unordered_map>
#include <typeinfo>

struct FunctorSum {
    int operator()(int x, int y) {
        return x + y;
    }
};
struct FunctorMult {
    int operator()(int x, int y) {
        return x * y;
    }
};

int main() {
    std::unordered_map<size_t, int> funcToInt;
    funcToInt[typeid(FunctorSum).hash_code()] = 0;
    funcToInt[typeid(FunctorMult).hash_code()] = 1;

    return 0;
}

这里我用了typeid作为hash,不过也可以硬编码成functor struct。

另一种方法是使用 std::function::target_type 来计算函数的哈希值,这仅适用于 lambdas。但是您始终可以将任何函数包装到 lambda 中。

#include <iostream>
#include <functional>

using FuncType = std::function<bool(int)>;
bool x(int v) { return v == 0; }

std::string hash(FuncType f) {
    return f.target_type().name();
}

int main() {
    auto y = [](int v) { return v == 1; };
    auto z = [](int v) { return v == 2; };

    std::cout << "x: " << hash(x) << std::endl;
    std::cout << "y: " << hash(y) << std::endl;
    std::cout << "z: " << hash(z) << std::endl;

    return 0;
}

输出

x: PFbiE
y: Z4mainEUliE_
z: Z4mainEUliE0_