与工会合作时我需要 `std::launder` 吗?

问题描述 投票:0回答:1

考虑以下代码:

#include <iostream>
#include <string>

union U
{
    std::string s;

    U()
    {
        new(&s) std::string;
    }

    void Set(std::string new_s)
    {
        s.~basic_string();
        new(&s) std::string(std::move(new_s));
    }

    ~U()
    {
        s.~basic_string();
    }
};

int main()
{
    U u;
    u.Set("foo");
    std::cout << u.s << '\n'; // Do I need `std::launder` here?
}

我知道,如果我使用字节数组而不是联合,我必须

std::launder(&s)
才能访问该字符串。但我这里需要它吗?

常识的答案似乎是“否”,但是标准在哪里祝福

union
不需要
std::launder

c++ language-lawyer stdlaunder
1个回答
0
投票

u.s
只是定义为产生指向联合的
s
成员子对象的指针。 (即使
u.s
不在其生命周期内,即不处于活动状态,也是如此。)

所以不需要清洗。您已经拥有所需对象的左值。

即使您从指向联合对象的指针开始并尝试使用指针转换方法(更类似于字节数组方法),那么它仍然可以在没有

std::launder
的情况下工作,例如:

std::cout << *reinterpret_cast<std::string*>(&u) << '\n';

这是因为联合对象与每个 [basic.compound]/4.2 的任何成员子对象都是指针可相互转换的,这意味着

reinterpret_cast
将立即生成指向成员子对象的指针。

© www.soinside.com 2019 - 2024. All rights reserved.