我想使用 lambda 函数在引用计数对象上异步调用方法:
void RunAsync(const std::function<void()>& f) { /* ... */ }
SmartPtr<T> objPtr = ...
RunAsync([objPtr] { objPtr->Method(); });
创建 lambda 表达式显然会创建一个拷贝,但我现在有一个问题,将 lambda 表达式转换为 std::function
对象也会创建一堆我的智能指针的拷贝,每个拷贝都会增加引用计数。
以下代码应演示此行为:
#include <functional>
struct C {
C() {}
C(const C& c) { ++s_copies; }
void CallMe() const {}
static int s_copies;
};
int C::s_copies = 0;
void Apply(const std::function<void()>& fct) { fct(); }
int main() {
C c;
std::function<void()> f0 = [c] { c.CallMe(); };
Apply(f0);
// s_copies = 4
}
虽然之后引用量恢复正常,但出于性能原因,我想防止引用操作过多。我不确定所有这些复制操作从何而来。
有没有什么方法可以用更少的智能指针对象拷贝来实现这一点?
更新:编译器是 Visual Studio 2010。
最佳答案
std::function
可能不会像自定义仿函数那样快,直到编译器对简单情况实现一些严格的特殊处理。
但是当 move
合适时,引用计数问题是复制的症状。正如其他人在评论中指出的那样,MSVC 没有正确实现 move
。您所描述的用法只需要移动,不需要复制,因此绝对不应触及引用计数。
如果可以,请尝试使用 GCC 进行编译,看看问题是否消失。
关于c++ - Lambda 到 std::function 的转换性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8298780/