sum*_*ght 5 c++ lambda finally c++11
我在C++ 11中使用lambda 创建了一个finally模拟器,如下所示:
#include <cstdio>
template<typename Functor>
struct Finalizer
{
Finalizer(Functor& func) : func_(func) {} // (1)
~Finalizer() { func_(); }
private:
Functor func_; // (2)
};
template<typename functor>
Finalizer<functor> finally(functor& func)
{
return Finalizer<functor>(func); (3)
}
int main()
{
int a = 20;
// print the value of a at the escape of the scope
auto finalizer = finally([&]{ printf("%d\n", a); }); // (4)
}
Run Code Online (Sandbox Code Playgroud)
代码按预期工作,但在Finalizer struct(1)的ctor处有不需要的copy ctor调用(lambda functor ).(值得庆幸的是,RVO可以避免在finally函数(3 - > 4)的return语句中进行复制构造.)
编译器不会消除copy ctor调用(至少在vc10中 - gcc可能会对其进行优化),如果Finalizer struct(2)中的仿函数类型被更改为引用它,则会因为finally调用时的lambda参数而崩溃( 4)是r值.
当然,代码可以像下面那样"优化"
template<typename Functor>
struct Finalizer
{
Finalizer(Functor& func) : func_(func) {}
~Finalizer() { func_(); }
private:
Functor& func_;
};
int main()
{
int a = 20;
auto finalizer = [&]{ printf("%d\n", a); };
Finalizer<decltype(finalizer)> fin(finalizer);
}
Run Code Online (Sandbox Code Playgroud)
没有开销,只有一个printf调用放在范围的末尾.但是......我不喜欢它.:(我试图用宏包装它,但它需要声明两个"名称" - 一个用于lambda对象,另一个用于终结器对象.
我的目标很简单 -
有没有解决办法避免这种情况?
我认为 lambda 具有移动构造函数?如果是这样,并且如果您只在 内部使用右值finally,那么&&和forward将移动而不是复制。
#include <cstdio>
template<typename Functor>
struct Finalizer
{
Finalizer(Functor&& func) : func_(std::move(func)) {}
Finalizer(Functor const& func) : func_(func) {} // (1)
~Finalizer() { func_(); }
private:
Functor func_; // (2)
};
template<typename functor>
Finalizer<std::remove_reference<functor>::type> finally(functor&& func)
{
return Finalizer<std::remove_reference<functor>::type>(std::forward<functor>(func)); // (3)
}
int main()
{
int a = 20;
// print the value of a at the escape of the scope
auto finalizer = finally([&]{ printf("%d\n", a); }); // (4)
}
Run Code Online (Sandbox Code Playgroud)
应该可以纠正一些更智能的东西,这些东西也可以与左值一起正常工作,这样你的“优化”版本就会编译并在无法移动时进行复制。在这种情况下,我建议您使用类似的方法来确保函子的类型正确,无论参数是否通过或其他方式Functor<std::remove_reference<functor>::type>传递。&&&
| 归档时间: |
|
| 查看次数: |
1649 次 |
| 最近记录: |