C++:如何制作由 std::function 索引的容器?
C++: How to make a container indexed by std::function?
对于索引,我使用 std::unordered_map
和 std::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_
对于索引,我使用 std::unordered_map
和 std::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_