c++ - 自动 xvalue 优化

标签 c++ c++11 move-semantics xvalue

有点令人惊讶(对我来说),以下两个程序编译成不同的输出,后一个具有更好的性能(用 gcc 和 clang 测试):

#include <vector>
int main()
{
    std::vector<int> a(2<<20);
    for(std::size_t i = 0; i != 1000; ++i) {
        std::vector<int> b(2<<20);
        a = b;
    }
}

对比

#include <vector>
int main()
{
    std::vector<int> a(2<<20);
    for(std::size_t i = 0; i != 1000; ++i) {
        std::vector<int> b(2<<20);
        a = std::move(b);
    }
}

有人可以向我解释为什么编译器会(或不能)在最后一次赋值中自动将 b 视为 xvalue 并在没有显式 std::move 的情况下应用 move 语义> Actor ?

编辑:用(g++|clang++) -std=c++11 -O3 -o test test.cpp

编译

最佳答案

Compilers can't break the as-if rule

如 §1.9/1 所述:

The semantic descriptions in this International Standard define a parameterized nondeterministic abstract machine. This International Standard places no requirement on the structure of conforming implementations. In particular, they need not copy or emulate the structure of the abstract machine. Rather, conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below

即编译器不能改变程序的可观察行为。自动(即使没有影响)将赋值转换为 move 赋值会破坏此语句。

复制省略可以稍微改变这种行为,但这是由 §12.8/31 规定的。

如果你想使用 move 版本,你必须像后一个例子一样明确要求它。

关于c++ - 自动 xvalue 优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26013183/

相关文章:

c++ - 防止子进程的控制台强制关闭

c++ - 为什么在超出容量时 resize() 会导致 vector 内容的复制而不是 move ?

c++ - std::map at 函数总是抛出异常

c++ - 确保模板参数是枚举类

functional-programming - move 语义对于 Rust 中的引用透明性意味着什么?

c++ - 何时使用 move 构造函数/赋值

c++ - 将指向数据成员的指针转换为 void *

c++ - Boost asio 异步读写

c++ - 我们如何以恒定复杂度或 O(1) 交换 2 个数组?

c++ - 不可复制的成员是否可以用作使对象不可复制的替代方法?