c++ - C++ lambda 真的会复制通过复制捕获的参数吗?

标签 c++ lambda language-lawyer compiler-optimization

在 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/

相关文章:

java - 如何将映射键值收集到列表中

c++ - move lambda : once you've move-captured a move-only type, 如何使用 lambda?

c - Unisys 最新的大型机系统是否仍然使用补码表示?

c++ - 如果 Derived 不向 Base 添加新成员(并且是 POD),那么可以安全地完成什么样的指针转换和取消引用?

c++ - 表达式的求值会在什么情况下发生

c++ - 三元和逗号运算符

c++ - 编写 Bash 脚本来计算平均值

c++ - 是否可以在 C++ 中创建 "friend class"?

c++ - 在 Qt 中使用 Mac 风格

java - 为什么 Optional 不提供 peek 方法?