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

Why is std::variant unable to hold array object types while union can?

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

static union
{
    uint64_t a;
    uint8_t b[8];
};

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

std::variant<uint64_t, uint8_t[8]> v

cppReference明确指出,

Template parameters

Types - the types that may be stored in this variant. All types must be (possibly cv-qualified) non-array object type

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

Error C2338 variant requires all of the Ts to be non-array object types ([variant.variant]/2).


std::variant 主要是一个 class 模板,因此, 问题是它无法推断数组类型存储,因为它只需要数据 layout/representation 吗?

P0510R0 after national body comment US116 中删除了对数组的支持,我在下面重现:

Support for array alternatives does not seem to work as expected. For example, if any of the alternatives is an array, the current specification fails to satisfy the Requires clause for all 6 relational operators, and loses (shall not participate in overload resolution) the copy constructor, move constructor, copy-assignment operator, move-assignment operator (although the swap functions will work correctly). It is difficult to activate an array alternative - to the best of my understanding, it must be emplaced with no arguments in order to value-initialize the array, and then the value of each element may be assigned as needed. Many of these issues would be resolved if array alternatives were implemented by storing a std::array instead, and then exposing the exposition-only array member (of the std::array) to the get functions, but that seems like an experimental change that should be investigated for the next standard. For C++17, we should drop support for arrays (but not std::array) as alternatives, in order to leave freedom to support them properly in the next standard.

std::variant 提案的初始修订期间,似乎没有太多考虑数组类型的可能性,尽管有些人认为 引用和 void 类型的情况(在 P0510R0 中也删除了对它们的支持),并且一些修订通过强加 Destructible 要求(最终标准文本中不存在)隐含地禁止数组。标准草案发送给国家成员机构后,有人注意到数组会带来困难,因为它们无法以预期的方式复制、移动或比较。也许所有这些问题都可以通过规范和实现中的 special-casing 数组来解决(member-wise 比较等),但是这项工作留给了标准的未来修订。