在 C++ 中使用带有按值捕获的变量的 lambda 函数意味着 copy of the value .
有了好的编译器,假设我们不修改 lambda 函数内的值,我们是否希望代码编译和优化后不会有实际拷贝?
例如,在下面将 new_item
作为值传递似乎是有意义的,因为它是在只读模式下使用的。
void loadavg_file::add(loadavg_item const & new_item)
{
auto const & it(std::find_if(
f_items.begin(),
f_items.end(),
[new_item](auto const & item)
{
return (item.f_address == new_item.f_address);
}));
if(it == f_items.end())
{
f_items.push_back(it);
}
else
{
// replace existing item with new avg and timestamp
it->f_timestamp = new_item.f_timestamp;
it->f_avg = new_item.f_avg;
}
}
是否会优化循环并导致完全没有 new_item
的拷贝?
最佳答案
如果 new_item
的复制构造函数(即 loadavg_item::loadavg_item(loadavg_item const&)
)具有除内存分配之外的可观察效果,则必须观察这些效果以发生(只要,你知道,你真的努力观察它们)。
这是因为您可能依赖于发生的那些副作用,并且这不是允许复制省略的上下文;仅当返回函数的值时才允许(并且后来强制执行)复制省略。另一方面,内存分配省略在任何地方都是允许的(遵守 [expr.new]/10 中的规则); clang 尤其擅长这一点。
检查生成的程序集不算作观察副作用,在调试器中运行程序也不算。
如果 new_item
的复制构造函数是非内联的,那么翻译单元的程序集可能会以符号的形式展示对复制构造函数的调用,但链接时优化 (LTO) 仍然可以如果链接时优化器可以推断出复制构造函数没有可观察到的副作用,则省略该调用。
关于c++ - C++ lambda 真的会复制通过复制捕获的参数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38857084/