为什么std :: variant在union可以不能保存数组对象类型?

Bud*_*nga 11 c++ variant visual-c++ c++17 c++20

这是一个简单的例子,我们可以union像这样定义一个低级别:

static union
{
    uint64_t a;
    uint8_t b[8];
};
Run Code Online (Sandbox Code Playgroud)

但是我们不能这样声明std::variant(请不要关心语法,如果我错了就纠正我!,只是抓住这个想法)

std::variant<uint64_t, uint8_t[8]> v
Run Code Online (Sandbox Code Playgroud)

cppReference明确指出,

模板参数

类型 - 可以存储在此变体中的类型.所有类型必须是(可能是cv限定的)非数组对象类型

此外,MSVC-v141(C++ 17)编译器给出了编译错误:

错误C2338变体要求所有Ts都是非数组对象类型([variant.variant]/2).


std::variant主要是一个类模板因此, 问题是它无法推断出数组类型存储,因为它只需要数据布局/表示

Bri*_*ian 17

国家机构评论US116之后,在P0510R0中删除了对阵列的支持,我在下面重现:

对数组备选方案的支持似乎没有按预期工作.例如,如果任何替代方案是数组,则当前规范无法满足所有6个关系运算符的Requires子句,并且丢失(不应参与重载解析)复制构造函数,移动构造函数,复制赋值运算符,移动-assignment运算符(尽管交换函数可以正常工作).很难激活一个数组替换 - 据我所知,为了对数组进行值初始化,必须在没有参数的情况下放置它,然后可以根据需要分配每个元素的值.如果通过存储std :: array来实现数组替代,然后将只有展示的数组成员(std :: array)暴露给get函数,那么很多这些问题都会得到解决,但这似乎是一个实验性的改变应该调查下一个标准.对于C++ 17,我们应该放弃对数组(但不是std :: array)的支持作为替代,以便在下一个标准中自由地支持它们.

这很可能是在最初的修订std::variant建议,没有太多的想法是给数组类型的可能性,但也有一些想法给(对这些支持也是P0510R0移除)的参考和无效的事例,有的修订版通过强加Destructible要求(最终标准文本中不存在)隐含地禁止数组.一旦将标准草案发送给国家成员机构,就会有人注意到阵列会造成困难,因为它们无法以预期的方式进行复制,移动或比较.所有这些问题也许可以通过规范和实现中的特殊套管阵列(成员比较等)来解决,但是这项工作留待将来修订标准.