std::variant是否允许为其成员分配内存?

25

我在想,std::variant 的实现是否必须是“平坦的”,或者它是否允许为其成员动态分配内存,使得一系列变体会退化为指针序列,从而破坏缓存局部性。


我在标题中添加了“flat”一词,因为我最初就是搜索这个词的。我会将其放在问题正文中,以便进行搜索,同时保留您提出的更具描述性的标题。 - bitmask
2个回答

30

非常明确,根据[variant.variant]:

任何时候,variant的实例要么持有其备选类型中的一个值,要么不持有任何值。当variant的实例持有备选类型T的值时,这意味着T类型的值,被称为变体对象的包含值,分配在variant对象的存储中。 实现不允许使用额外的存储,如动态内存,来分配包含的值。 所包含的值应该分配在适合于Types...中所有类型的variant存储区域中,适当对齐。是否支持超对齐类型是由实现定义的。


2
@0x5453 嗯,不是吧?这绝对是允许的。这样的限制没有任何意义,也无法执行。Clang之所以拒绝它是因为 这个原因 - Barry
没错,现在我重新阅读标准的措辞后就明白了。谢谢。 - 0x5453
7
含有向量的变体并不进行任何动态分配,向量本身在进行动态分配。这与在变体中具有指针类型没有什么区别--您可以在那里存储指向动态内存的指针。@0x5453 - Barmar
1
@Barry:实际上,我对标准中包含这样明确的声明感到非常惊讶。毕竟,“元组”没有类似的措辞,尽管基本上没有任何实现会为其成员动态分配存储空间。 - Nicol Bolas
4
据我所知,tuple确实需要要求:对于每个元组构造函数,只有在Types中的某种类型构造引发异常时才会抛出异常。这意味着它不能动态分配。 - NathanOliver
显示剩余2条评论

9
根据cppreference::std::variant不得分配动态内存。
与联合体一样,如果一个变量保存了某个对象类型 T 的值,则 T 对象的对象表示直接分配在变量自身的对象表示中。Variant 不允许分配额外(动态)内存。

1
我不确定这个问题是否有用,特别是因为答案没有引用标准。 - Incomputable
6
我很抱歉,但我需要原始的上下文才能提供准确的翻译。 - bolov
@Incomputable 在谷歌上找到的答案并不能为这个社区的内容增加任何价值。我不在乎你是否能用谷歌找到答案。如果这是一个好问题,我希望它出现在stackoverflow上。 - bolov
@bolov,如果有更好的文档资料在其他地方,那么就不应该在这里提出。我相信它已经写在帮助中心的某个地方了。但是,确实有太多的C++问题在这里,所以把它们放在一个地方可能是个好主意。 - Incomputable
3
我同意我应该直接从标准中获取答案,而不是从cppreference获取。但是我认为cppreference和标准一样好(而且更容易浏览)。 - bitmask
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接