自动xvalue优化

Xop*_*oph 12 c++ move-semantics xvalue c++11

有点令人惊讶(对我来说),以下两个程序编译成不同的输出,后者有更好的性能(用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;
    }
}
Run Code Online (Sandbox Code Playgroud)

#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);
    }
}
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释为什么编译器会(或可以)不自动考虑b最后一个赋值中的xvalue并在没有显式强制转换的情况下应用移动语义std::move吗?

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

Mar*_* A. 7

编译器不能破坏as-if规则

如§1.9/ 1所述:

本国际标准中的语义描述定义了参数化的非确定性抽象机器.本国际标准对符合实施的结构没有要求.特别是,它们不需要复制或模拟抽象机器的结构.相反,需要符合实现来模拟(仅)抽象机器的可观察行为,如下所述

即编译器无法更改程序的可观察行为.自动(即使没有任何影响)将分配转换为移动分配会破坏此陈述.

复制权限可以稍微改变这种行为,但这受§12.8/ 31的约束.

如果您想使用移动版本,则必须在后一个示例中明确要求它.

  • 在这个特定的代码中,它不会破坏as-if规则,因为没有输出 (2认同)

Mir*_*pas 5

让我们看看下一个示例(请忽略void返回类型operator=):

#include <iostream>

struct helper
{
    void operator=(helper&&){std::cout<<"move"<<std::endl;}
    void operator=(const helper&){std::cout<<"copy"<<std::endl;}
};

void fun()
{
    helper a;
    {
        helper b;
        a = b;
    }
}

void gun()
{
    helper a;
    {
        helper b;
        a = std::move(b);
    }
}
int main()
{
    fun();
    gun();
}
Run Code Online (Sandbox Code Playgroud)

operator=这取决于它的参数有不同的行为.只有在能够保持可观察行为相同的情况下,才允许编译器优化代码.

bfuna开始考虑xvalue,虽然它不是xvalue在调用的那一刻它将改变程序的可观察行为,这是标准不希望也不允许的.