【发布时间】:2017-09-11 20:06:35
【问题描述】:
此代码仅用于说明问题。
#include <functional>
struct MyCallBack {
void Fire() {
}
};
int main()
{
MyCallBack cb;
std::function<void(void)> func = std::bind(&MyCallBack::Fire, &cb);
}
valgrind 的实验表明,分配给func 的行在 linux 上使用 gcc 7.1.1 动态分配了大约 24 个字节。
在实际代码中,我有几个不同的结构,它们都有一个 void(void) 成员函数,存储在大约 1000 万个 std::function<void(void)> 中。
有什么办法可以避免在执行 std::function<void(void)> func = std::bind(&MyCallBack::Fire, &cb); 时动态分配内存? (或者以其他方式将这些成员函数分配给std::function)
【问题讨论】:
-
@BeyelerStudios,对函数的分配器支持已从 2017 C++ 中删除。
-
@BeyelerStudios 强制使用 lambda 是一件好事。
-
@BeyelerStudios 类型擦除总是有运行时成本。如果您想避免这种情况,您可以将使用
std::function的函数重写为采用任意可调用类型的模板。编译时工作和运行时工作之间的这种权衡一直存在于 C++ 中。 -
即使超出这个特定情况,如果给定的答案是正确的,应该只是在 C++14 及更高版本中几乎完全避免绑定。可能在某些极端情况下仍然可以,但在 99.9% 的情况下,您应该使用 lambda。
-
问题是,即使提出了使用 lambda 解决直接问题的解决方案,lambda/
std::function仍然存储指向结构的指针,因此数据仍然会超出-线。所以如果你说vector<function<void(void)>>,你仍然会疯狂地触发缓存未命中并且性能很差。您将只有一个间接而不是双重间接。如果您的各种结构都具有相似的大小,您可以做得更多、更好、更好。他们是吗?你有几个?