如果存储原始参考的类不在范围之外,可以捕获会员参考安全吗?
Is it safe to capture a member reference if the class storing the original reference goes out of scope?
考虑以下内容:
#include <iostream>
#include <functional>
std::function<void()> task;
int x = 42;
struct Foo
{
int& x;
void bar()
{
task = [=]() { std::cout << x << 'n'; };
}
};
int main()
{
{
Foo f{x};
f.bar();
}
task();
}
我的本能是,由于执行任务时实际的指称仍然存在,因此我们在遇到lambda时获得了新的参考,并且一切都很好。
但是,在我的GCC 4.8.5(CentOS 7)上,我看到一些行为(在一个更复杂的程序中)表明这是UB,因为f
和参考f.x
本身已经死亡。是吗?
要捕获成员参考,您需要使用以下语法(在C 14中引入):
struct Foo
{
int & m_x;
void bar()
{
task = [&l_x = this->m_x]() { std::cout << l_x << 'n'; };
}
};
这样的方式l_x
是存储在闭合中的int &
,指的是同一int
值m_x
是引用的,并且不受Foo
的影响。
在C 11中,我们可以通过对指针进行价值而丢失此功能:
struct Foo
{
int & m_x;
void bar()
{
int * p_x = &m_x;
task = [=]() { std::cout << *p_x << 'n'; };
}
};
您可以通过创建参考和显式捕获的本地副本来捕获C 11中的参考成员,以避免捕获this
:
void bar()
{
decltype(x) rx = x; // Preserve reference-ness of x.
static_assert(std::is_reference<decltype(rx)>::value, "rx must be a reference.");
task = [&rx]() { std::cout << rx << ' ' << &rx << 'n'; }; // Only capture rx by reference.
}
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 虚拟决赛作为安全
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- C++错误消息*成员参考.**初学者*
- 如何将元素添加到数组的线程安全函数?
- C++中的线程安全删除
- 在决定是通过参考还是通过价值时,尺寸真的是一个问题吗
- 通过网络、跨平台传递std::变体是否安全
- 参考资源文件VC++中的$(SolutionDir)
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 在std::thread中,joinable()然后join()线程安全吗
- 使用std::istream::peek()总是安全的吗
- 从值小于256的uint16到uint8的Endian安全转换
- 在c++队列中使用pop和visit实现线程安全
- 在类型和包装器之间reinterpret_cast是否安全<Type>?
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- 为什么在运算符重载时需要参考?
- 保留对tbb :: concurrent_unordered_map项目的参考安全吗?
- 如果存储原始参考的类不在范围之外,可以捕获会员参考安全吗?