2

假设我们有一个变量

std::optional<T> x;

std::optional<T>某种类型的类型T。如果我想调用Tinside的构造函数x并对其进行初始化,我可以调用成员函数std::optional::emplace。据我所知,这个成员函数检查实例是否已经存在(即bool(x)计算结果为true),如果是这样,它首先销毁先前构造的实例,然后使用提供的构造函数和参数重新初始化它。

我想知道是否可以只进行初始化而不进行这种检查和销毁。在处理 时std::optional,首先检查实例是否存在然后根据结果进行一些单独的工作似乎很常见。因此,似乎有理由认为,当我们需要在内部放置一个实例时std::optional,我们已经知道它不包含任何已初始化的实例。std::optional::emplace因此,提供一个不检查和破坏先前实例但std::optional没有这样的成员函数的“不安全版本”似乎是合理的。有没有办法做到这一点?

也许,如果有一些关于内存布局的保证std::optional(我猜不是),那么我可以直接调用放置new运算符......

4

1 回答 1

2

不,这是不可能的。不,直接调用placementnew到内存也无济于事,因为您还必须在指示中设置标志以optional指示已启用optional-您不能在外部执行此操作。

因此,似乎有理由认为,当我们需要在内部放置一个实例时std::optional,我们已经知道它不包含任何已初始化的实例

这不是一个强有力的论点。emplace()只是operator=optional.

此外,如果您的代码结构如下:

if (!o) {
    // stuff
    o.emplace(some, args, here);
}

您可以放心,您的编译器会看到explicit operator bool()检查和内部emplace()检查之间的重复分支并将它们折叠在一起,因此不会有额外的分支。

于 2017-03-10T17:45:06.720 回答