为什么 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 比较等),但是这项工作留给了标准的未来修订。
这是一个简单的例子,
我们可以像这样定义一个低级别 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 比较等),但是这项工作留给了标准的未来修订。