我想使用lambda函数异步调用引用计数对象上的方法:
void RunAsync(const std::function<void()>& f) { /* ... */ }
SmartPtr<T> objPtr = ...
RunAsync([objPtr] { objPtr->Method(); });
Run Code Online (Sandbox Code Playgroud)
创建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
}
Run Code Online (Sandbox Code Playgroud)
虽然之后引用的数量恢复正常,但出于性能原因,我希望防止过多的引用操作.我不确定所有这些复制操作的来源.
有没有办法用更少的智能指针对象副本实现这一点?
更新:编译器是Visual Studio 2010.
std::function 在编译器对简单案例进行一些严肃的特殊处理之前,可能不会像自定义函子那么快.
但引用计数问题move是适当时复制的症状.正如其他人在评论中指出的那样,MSVC没有正确实施move.您所描述的用法仅需要移动而不是复制,因此不应触及引用计数.
如果可以,尝试使用GCC进行编译,看看问题是否消失.
| 归档时间: |
|
| 查看次数: |
4727 次 |
| 最近记录: |