为什么std的构造::可选的比std::pair更贵?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (39)

考虑可以代表“可选int”的这两种方法:

using std_optional_int = std::optional<int>;
using my_optional_int = std::pair<int, bool>;

鉴于这两个功能...

auto get_std_optional_int() -> std_optional_int 
{
    return {42};
}

auto get_my_optional() -> my_optional_int 
{
    return {42, true};
}

... g ++ trunkclang ++ trunk (带-std=c++17 -Ofast -fno-exceptions -fno-rtti产生下列组件:

get_std_optional_int():
        mov     rax, rdi
        mov     DWORD PTR [rdi], 42
        mov     BYTE PTR [rdi+4], 1
        ret

get_my_optional():
        movabs  rax, 4294967338 // == 0x 0000 0001 0000 002a
        ret

为什么get_std_optional_int()需要三条mov指令,而get_my_optional()只需要一条movabs?这是一个QoI问题,还是有什么std::optional阻止这种优化的规范?

另请注意,无论使用哪种功能,用户都可以完全优化:

volatile int a = 0;
volatile int b = 0;

int main()
{
    a = get_std_optional_int().value();
    b = get_my_optional().first;
}

...结果是:

main:
        mov     DWORD PTR a[rip], 42
        xor     eax, eax
        mov     DWORD PTR b[rip], 42
        ret
提问于
用户回答回答于

你可以通过以下方式验证它

static_assert(std::is_trivially_copyable_v<std::optional<int>>);
用户回答回答于

直接原因是在寄存器中optional返回时通过隐藏指针pair返回。

如果C ++对象具有非平凡的拷贝构造函数或非平凡的析构函数,它将通过不可见的引用传递。

扫码关注云+社区

领取腾讯云代金券