我对于应该如何std::optional实现复制构造函数以满足存在的要求感到非常困惑constexpr。
请注意,在Stackoverflow上还有许多其他问题类似的问题,例如:
std :: Optional实现为union vs char [] / aligned_storage
但是,这两个问题都没有真正询问“ COPY CONSTRUCTOR”。我专门询问具有功能签名(从https://en.cppreference.com/w/cpp/utility/optional/optional)的副本构造函数,如下所示:
constexpr optional( const optional& other );
Run Code Online (Sandbox Code Playgroud)
现在,我已经阅读了足够std::optional的知识,以了解基础知识。实现者通常犯的一个错误是尝试使用来实现它std::aligned_storage。由于new放置不能在中使用constexpr(至少在C ++ 17中),因此将不起作用。相反,需要使用联合类型,以便可以直接构造它。就像是:
struct dummy_type {};
union optional_impl
{
dummy_type m_dummy;
T m_value;
};
Run Code Online (Sandbox Code Playgroud)
好的,但是仍然...我仍然看不到应该如何满足将副本构造函数实现为的要求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
}
Run Code Online (Sandbox Code Playgroud)
我看到此工作的唯一方法是使用新的展示位置。
所以我检查了一些实际的实现,例如这里的gcc实现:
https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/std/optional#L248
实际上,他们只是使用新的展示位置。实际上,复制构造函数不是事件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只要函数模板(或类模板的成员函数)具有至少一个可能在常量表达式中使用的实例化,就可以对其进行声明。([dcl.constexpr] / 6)
在C ++ 20中,由于P0602R4,措辞已更改。但是,我认为这并没有改变constexpr要求。如果T是普通可复制的,则构造函数是普通的,这意味着它也是constexpr。如果T不是普通可复制的,则标准不会说构造函数必须在常量表达式中可用,因此没有这样的要求。
| 归档时间: |
|
| 查看次数: |
109 次 |
| 最近记录: |