相关疑难解决方法(0)

理解C++ 0x lambda捕获

在最近的一个C++ 0x草案(n3225.pdf)中,我们可以找到5.1.2/10:

使用通常的非限定名称查找规则(3.4.1)查找捕获列表中的标识符; 每个这样的查找应该找到一个变量,其自动存储持续时间在本地lambda表达式的到达范围内声明.如果实体(即变量或此实体)出现在lambda表达式的捕获列表中,则称其被明确捕获.

这对我来说似乎相当严格.例如,在我看来,以下事情是不允许的:

int global;

struct s {
    int x;
    void memfun() {
        [x,global]{};
    }
};
Run Code Online (Sandbox Code Playgroud)

因为x不一定是具有自动存储的变量,也不是global.请注意,此捕捉条款的用意是让拉姆达对象存储复制x,并global可能是可取的情况下,他们在后一阶段发生变化.我已经知道了另一种选择:

int global;

struct s {
    int x;
    void memfun() {
        int copyx = x;
        int copyglobal = global;
        [copyx,copyglobal]{};
    }
};
Run Code Online (Sandbox Code Playgroud)

但这归结为额外的副本和额外的锅炉板只是为了捕获xglobal复制.

此外,我在最新的草稿中找不到任何结论,如果我们在捕获子句中命名本地引用会发生什么:

int main() {
    int  i = 0;
    int &r = i;
    assert([r]{return &r;}() != &i);
}
Run Code Online (Sandbox Code Playgroud)

lambda对象"复制引用"还是"复制int"?如果它通过副本捕获引用的对象,这可以节省我们之前的解决方案中的其他副本.

GCC显然支持所有这些示例,并在最后一种情况下存储一个int的副本(这是可取的,恕我直言).但我想知道这是否实际上是根据C++ 0x草案的预期行为,或者只是一个编译器扩展,分别是一个实现bug.

编辑: …

lambda c++11

12
推荐指数
1
解决办法
1894
查看次数

按值捕获成员变量

使用C++ 11 lambda表达式时,如何按值捕获成员变量?

使用[my_member]语法似乎不起作用,隐式捕获使用this指针.需要的是一种明确指定成员变量的捕获类型的方法.那可能吗?

我现在的解决方法是:

void member_function()
{
    std::shared_ptr<my_member_class> my_member_copy = my_member; // this shouldn't be necessary
    std::async([=]{ std::cout << *my_member_copy; });
    // std::async([=]{ std::cout << *my_member_; }); // wrong, my member could be potentially out of scope
}
Run Code Online (Sandbox Code Playgroud)

c++ lambda c++11

9
推荐指数
2
解决办法
5303
查看次数

C++ lambda不会对按值捕获的成员调用析构函数

我今天在XCode下对lambdas的这种奇怪行为感到非常痛苦 - 在尝试跟踪iOS中围绕代码的几个内存泄漏之后,我将其缩小到这个(和类似的)代码片段,在那里我分配所有权使用共享指针的延迟任务的东西:

void DBStorage::dispose(std::shared_ptr<DataChunk>& dc)
{
    backgroundQueue.queueTask([=]() {
        assert( dc.use_count() == 1 );

        if (dc->isDirty()) {
            //store to disk
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

(注意,运行lambda时共享指针的使用计数始终为1)

在执行之后,这个任务是null-ified pendingJob = nullptr;,我希望它可以调用所有按值捕获的对象的析构函数,从而调用析DataChunk构函数.但是,看起来在XCode/LLVM下 lc的析构函数永远不会被调用; 明确地调用它的dtor,使用mutable和删除std::function简单的delete也不起作用.

这是标准行为吗?我当然可以手动调用dc.reset()它按预期工作,但这很有必要使用共享指针.


解决方案 显然,这是一个已知的gcc bug.


的Contrib

具有Xcode 5.0.2/clang 3.3输出的独立样品

#include <iostream>
#include <memory>

void fnRef(std::shared_ptr<int>& ptr)
{
    auto lambda = [=]() { std::cout << ptr.use_count() << ':' << __PRETTY_FUNCTION__ << '\n'; };
    lambda();
}

void fnVal(std::shared_ptr<int> ptr) …
Run Code Online (Sandbox Code Playgroud)

c++ lambda xcode llvm c++11

9
推荐指数
1
解决办法
1390
查看次数

Lambda通过引用捕获引用变量

对于一个lambda,我想通过引用捕获一些东西,它已经通过引用保存在外部作用域中.假设引用的值超过lambda,但不是lamdba创建的范围.

我知道如果lambda 按值捕获引用变量,则会复制引用的对象.我想避免这个副本.

但是如果我通过引用捕获引用变量会发生什么?如果在执行lambda之前原始引用变量超出范围会怎么样?这样安全吗?换句话说:引用的引用后面的对象是lambda中引用的引用变量吗?

auto f() {
    const auto & myRef = g();
    return [&]{ myRef.doSomething(); };
}

f()();  // Safe?
Run Code Online (Sandbox Code Playgroud)

c++ lambda c++11

6
推荐指数
1
解决办法
3666
查看次数

标签 统计

c++11 ×4

lambda ×4

c++ ×3

llvm ×1

xcode ×1