C++ lambda 构造函数参数是否可以捕获构造的变量
Can a C++ lambda constructor argument capture the constructed variable?
以下编译。但是,有没有任何形式的悬而未决的参考问题?
class Foo {
Foo(std::function<void(int)> fn) { /* etc */ }
}
void f(int i, Foo& foo) { /* stuff with i and foo */ }
Foo foo([&foo](int i){f(i, foo);});
似乎有效。(真正的lambda当然更复杂。
但是,有没有任何形式的悬而未决的参考问题?
这完全取决于您对Foo
做什么。下面是一个存在悬而未决的参考问题的示例:
struct Foo {
Foo() = default;
Foo(std::function<void(int)> fn) : fn(fn) { }
std::function<void(int)> fn;
}
Foo outer;
{
Foo inner([&inner](int i){f(i, inner);});
outer = inner;
}
outer.fn(42); // still has reference to inner, which has now been destroyed
lambda 表达式[&foo](int i){f(i, foo);}
将导致编译器生成这样的闭包类(但不完全正确):
class _lambda
{
Foo& mFoo; // foo is captured by reference
public:
_lambda(Foo& foo) : mFoo(foo) {}
void operator()(int i) const
{
f(i, mFoo);
}
};
因此,声明Foo foo([&foo](int i){f(i, foo);});
被视为Foo foo(_lambda(foo));
。在这种情况下,在构造时捕获foo
本身没有问题,因为这里只需要它的地址(引用通常通过指针实现)。
类型std::function<void(int)>
将在内部复制构造此lambda类型,这意味着Foo的构造函数参数fn
保存_lambda
对象的副本(该对象包含对foo
的引用(即mFoo)。
这意味着在某些情况下可能会出现悬而未决的参考问题,例如:
std::vector<std::function<void(int)>> vfn; // assume vfn live longer than foo
class Foo {
Foo(std::function<void(int)> fn) { vfn.push_back(fn); }
}
void f(int i, Foo& foo) { /* stuff with i and foo */ }
Foo foo([&foo](int i){f(i, foo);});
....
void ff()
{
// assume foo is destroyed already,
vfn.pop_back()(0); // then this passes a dangling reference to f.
}
相关文章:
- 没有用于初始化C++中的变量模板的匹配构造函数
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 在类构造函数中使用结构变量
- 在 c++ 中将变量作为结构构造函数中的引用传递
- 在类构造函数中定义结构变量的参数
- 修改程序的入口点时未调用全局变量的构造函数
- C++:将向量传递到构造函数以创建成员变量的最佳方法?
- 为什么从另一个构造函数内部调用C++构造函数不修改类变量?
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 构造函数干扰成员变量指定的初始值设定项?
- 类中的数组变量C++导致"was not declared in this scope"实现文件的一个函数中错误,但在构造函数中不会导致错误
- 通过 C++ 中的重载构造函数初始化未知类型的变量
- 如何在初始化列表中的构造函数之后初始化变量/对象?
- 我可以使用在类构造函数中初始化的流类型的成员变量吗?
- 为什么 std::move 不将默认移动构造函数中的源变量更改为默认值?
- C++为具有引用成员变量的类创建复制构造函数
- 带有常量构造函数参数的C++变量构造函数方法
- 全局变量构造函数/析构函数是否需要线程保护
- G++ 4.6 -std=gnu++0x:静态局部变量构造函数调用计时和线程安全
- 来自静态变量构造函数/析构函数的异常