减少 std::bind 模板代码膨胀?

Reducing std::bind template code bloat?

我写了一个存储 std::function<void(void*)> 的对象,它作为参数传递给构造函数。该对象稍后会在将来的某个时间回调此 std::function。这已经实现并且运行良好。

在每个使用这个对象的class中,他们调用初始化列表中的构造函数,如下所示:

mCallbackObj(std::bind(&MyClass::MyFunc, this, _1))

但是,我发现每个包含此对象作为成员的 class 都将我的代码空间增加了 ~2K。由于可能有数百个地方将使用此对象,并且代码空间选项有限(这是嵌入式产品),因此每次使用 2k 的点击率是不可接受的。

一个有趣的观察是,如果 class 有第二个对象:

mCallbackObj2(std::bind(&MyClass::MyOtherFunc, this, _1))

这只会增加约 150 字节的代码空间 - 非常可以接受!只有当对象用于不同的 classes 时,我才看到 2K 命中。将 classes 全部放在一个 .cpp 文件中没有帮助 - 每个包含此对象的 class 仍然有 2k 命中。

我尝试过使用 extern template class std::function<void(void*)>;,但这对 ROM 大小没有影响。

我正在使用 gcc 4.8。我喜欢使用 std::functionstd::bind,但即将放弃并切换到 class 方法指针。它们不会那么干净,但希望 ROM 效率更高。

在我放弃之前,是否有任何其他选项可以帮助减少我的模板代码空间膨胀?

我对此进行了深入研究并观看了 @John's video on std::function. In the video,出于某些原因,STL 建议在 std::bind 上使用 lambda。

我尝试将代码转换为使用 Lambda,这正是上面 @Igor Tandetnik 推荐的。明显好很多。

mCallbackObj(std::bind(&MyClass::MyFunc, this, _1))

占用额外的 2,888 字节代码空间。而是使用

mCallbackObj([this](void *info){MyFunc(info);})

只占用额外的812字节!这要好得多,并且对于我的用例来说已经足够好了。对于不熟悉 std::bind 语法的 C++ 程序员,lambda 解决方案也更易于阅读。


更新-

在升级到 GCC 6.0 并调整我们的编译器标志后(我们之前并不总是传入 -O2),我重新测试了这个。

Lambda:            216 bytes
std::bind:         221 bytes
function pointer:  228 bytes

所有 3 个现在都更加合理。我们主要使用 lambda,因为一旦开发人员熟悉语法,它们最容易阅读。