【问题标题】:why is_standard_layout gives true here?为什么 is_standard_layout 在这里给出 true ?
【发布时间】:2021-10-18 11:39:43
【问题描述】:

我的理解是,没有任何虚拟方法是标准布局的要求之一。但是,当 struct Cancel 中有一个虚方法时,以下代码会打印出 true。

如果我删除虚拟方法。 is_stand_layout 返回 false 这是有道理的,因为 Cancel 的成员具有不同的访问控制。

我在gcc 10.2、9.2 9.3和clang 11.0上测试过,结果是一样的。

这是一个错误吗?还是我在标准布局方面遗漏了什么?

#include <variant>
#include <iostream>

struct NewOrder
{
    int i;
};
struct Cancel
{
    virtual ~Cancel() {}
    int j;
private:
    int i;
}; 
int main() {
  std::cout << std::is_standard_layout_v<std::variant<NewOrder, Cancel>> << std::endl;
  return 0;
}

【问题讨论】:

  • 你不检查Cancel是否是标准布局,你检查std::variant&lt;NewOrder, Cancel&gt;是否是。那是一种完全不同且不相关的类型。
  • std::variant 的内部结构看起来像std::aligned_storage&lt;std::max({std::sizeof(Ts)...})&gt; buffer; bool alternative; 这都是标准布局。
  • @NathanOliver ,如果我删除虚拟方法。 is_standard_layout 将返回 false。所以只是变体的实现真的很棘手吗?
  • 啊,variant 确实有不同的实现,用于可破坏或不可破坏的结构。这很有道理,感谢您的帮助

标签: c++ stl g++ clang++


【解决方案1】:

这是一个错误吗?

没有。

我有什么遗漏的吗

您正在输出std::is_standard_layout_v&lt;std::variant&lt;NewOrder, Cancel&gt;&gt;,它确定std::variant&lt;NewOrder, Cancel&gt; 是否为标准布局,而不是Cancel 是否为标准布局。

为什么 is_standard_layout 在这里给出 true?

std::variant&lt;NewOrder, Cancel&gt; 是否为标准布局不一定取决于模板类型参数本身是否为标准布局。该标准没有指定 std::variant 是否是标准布局。您看到的输出是您使用的标准库中如何实现 std::variant 的副作用。

【讨论】:

  • 感谢您的解释。我认为变体只是多种类型的更好结合。太奇怪了,它是这样实现的。拥有虚拟功能将使标准布局成为现实,没有它就不是标准布局..也让我想知道标准布局的用途是什么。我认为这意味着它可以在 C 中访问。但我怀疑如何在 C 中访问像 std::variant 这样的结构。
  • 我看到该变体对于可平凡破坏和不可平凡破坏的模板类型有不同的实现。它就像是新订单和取消的直接联合,当取消是可轻易破坏的时,它是不同类型的联合,当取消不可轻易破坏时。现在这一切都说得通了,非常感谢。
猜你喜欢
  • 2013-04-06
  • 1970-01-01
  • 2020-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多