繁体   English   中英

std 可选的复制构造函数

[英]std optional copy constructor

我对如何实现std::optional的复制构造函数以满足constexpr的要求感到非常困惑。

请注意,Stackoverflow 上还有许多其他问题都在问类似的问题,例如:

如何实现 std::optional 的复制构造函数?

std::optional 实现为 union vs char[]/aligned_storage

但是,这些问题实际上都不是关于 COPY CONSTRUCTOR 的问题。 我特别询问带有 function 签名的复制构造函数(来自https://en.cppreference.com/w/cpp/utility/optional/optional )如下:

constexpr optional( const optional& other );


现在,我已经阅读了足够多的关于std::optional以了解基础知识。 实现者犯的一个典型错误是尝试使用std::aligned_storage来实现它。 由于放置 new 不能在constexpr中工作(至少在 C++17 中),所以这不起作用。 相反,需要使用联合类型,以便可以直接构造它。 就像是:

struct dummy_type {};

union optional_impl
{
  dummy_type m_dummy;
  T m_value;
};

好的,但仍然......我仍然不明白我们应该如何满足将复制构造函数实现为constexpr的要求。 问题是在复制构造函数中,我们需要检查other.has_value()是否为真。 如果是,我们想直接复制*other ,否则我们只想初始化m_dummy 但是我们如何在constexpr复制构造函数中表达这个条件决定呢?

constexpr optional( const optional& other ) : m_dummy{}
{
  if (other.has_value()) new (&m_value) T(*other); // Wrong! Can't use placement new
}

我能看到这个工作的唯一方法是使用placement new。

所以我检查了一些实际的实现,比如这里的 gcc 实现:

https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/std/optional#L248

事实上......他们只是使用新的展示位置。 事实上,复制构造函数不是 event constexpr (我猜这是一个缺陷)。

这是另一个实现:

https://github.com/akrzemi1/Optional/blob/master/optional.hpp#L416

再一次,他们只是使用新的展示位置。

那么optional(const optional&)怎么能被实现为constexpr呢? 这是标准的缺陷还是什么?

对于 C++17,请参见 [optional.ctor]/6:

...如果is_trivially_copy_constructible_v<T>true ,则此构造函数应为constexpr构造函数。

在那种情况下,联合也将是可简单复制的,所以没有问题。

在所有其他情况下,构造函数仍将携带constexpr说明符,即使它不能用于常量表达式。 这没关系:允许声明一个constexpr模板(或 class 模板的成员 function),只要它至少有一个可用于常量表达式的可能实例化。 ([dcl.constexpr]/6)

在 C++20 中,由于P0602R4 ,措辞发生了变化。 但是,我认为这并没有改变constexpr的要求。 如果T是可简单复制的,则构造函数是简单的,这意味着它也是constexpr 如果T不是普通可复制的,那么标准并没有说构造函数必须在常量表达式中可用,所以没有这样的要求。

看起来这是 C++17 (添加了 c++17 的 std::optional ),这意味着如果 arguments 正在编译,则 constexpr 将仅应用于 function

在这种情况下,它只是意味着如果你所有的 arguments 到 function 都是 constexpr 并且可以执行 constexpr,那么它实际上就是 constexpr。

否则,它就像任何其他复制 ctor 一样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM