C ++:可以优化未使用的lambda显式捕获吗?

时间:2012-10-03 23:42:41

标签: c++ lambda c++11 language-lawyer

当使用lambda表达式作为回调来确保我的实例保持活动时,我有相当数量的代码依赖于捕获shared_from_this()

std::shared_ptr<Thing> self = shared_from_this();
auto doSomething = [this, self] ()
{
    // various statements, none of which reference self, but do use this
}

所以问题是:由于我没有在lambda体内引用self,是否允许一致的编译器优化捕获?


考虑以下计划:

#include <functional>
#include <iostream>
#include <memory>

std::function<void ()> gFunc;

struct S : std::enable_shared_from_this<S>
{
    void putGlobal()
    {
        auto self = shared_from_this();
        gFunc = [self] { };
    }
};

int main()
{
    auto x = std::make_shared<S>();
    std::cout << x.use_count() << std::endl;
    x->putGlobal();
    std::cout << x.use_count() << std::endl;
}

输出结果为:

1
2

这表明g++-4.7.1没有优化捕获(clang-3.1也没有)。

1 个答案:

答案 0 :(得分:31)

该标准保证捕获的值不被优化(根据§5.1.2/ 14):

  

如果隐式捕获实体,并且捕获默认值为=,或者明确是,则按副本捕获实体   使用不包含&amp;的捕获捕获对于通过副本捕获的每个实体,未命名的非   静态数据成员在闭包类型中声明。未指定这些成员的声明顺序。   如果实体不是a,则这种数据成员的类型是相应的捕获实体的类型   引用对象,否则引用的类型。

因此,self被复制到评估的闭包中(根据§5.1.2/ 21):

  

评估lambda表达式时,复制捕获的实体用于直接初始化   生成的闭包对象的每个对应的非静态数据成员。