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

时间:2015-11-04 23:26:02

标签: c++ templates c++11 bind stdbind

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

在每个使用该对象的类中,它们都像初始化列表一样调用构造函数:

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

但是,我发现每个包含此对象作为成员的类正在将代码空间增加~2K。可能有数百个使用此对象的地方,以及有限的代码空间选项(这是一个嵌入式产品),每次使用2k命中率是不可接受的。

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

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

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

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

我正在使用gcc 4.8。我喜欢使用std::functionstd::bind,但我要放弃并切换到类方法指针。他们不会那么干净,但希望更有效率。

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

1 个答案:

答案 0 :(得分:1)

我进一步挖掘了这一点,并在bool more3dec = Regex.IsMatch(input, @"\d+\.\d+\.\d+"); 上观看了@John的视频。在video中,由于某些原因,STL建议在std::function上使用lambdas。

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

std::bind

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

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

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

更新 -

在碰到GCC 6.0并调整我们的编译器标志之后(我们之前并没有总是在-O2中传递),我已经重新测试了这个。

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

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