当前位置: 首页 > 知识库问答 >
问题:

如果绝对没有调用成员函数,是否允许使用类型不完整的向量?如果是,从什么时候开始的?

沃瑾瑜
2023-03-14

假设我有某种不完整的类型

// in foo.hh
struct Hidden;

我希望将其用作std::vector的元素类型。使用union,我可以将对std::vector的构造函数和析构函数的调用“推迟”到unions构造函数/析构函数的实现。

// in foo.hh
struct Public {
  union Defer {
    std::vector<Hidden> v;
    Defer();
    // add copy/move constructor if needed
    ~Defer();
  } d;
};

现在,我可以使用public,方法是只包含foo.hh并与实现public::defer::defer()public::defer::~defer()的文件链接。只有那些用户才需要访问hidden的完整定义。

这是合法的C++吗?如果是,从什么时候开始的?

背景:我在回答另一个问题时提出的问题。

共有1个答案

丁高峯
2023-03-14

使用不完整类型实例化std::vector t是C++14之前的未定义行为。在C++17中,这一限制有所放宽:

[vector.overview]/3如果分配器满足分配器完整性要求17.6.3.5.1,则在实例化vector时可以使用不完整类型T。在引用生成的vector专门化的任何成员之前,t必须完整。

(注意:默认的分配器std::allocator确实满足这些完整性要求)。

我的理解是,在C++17中,翻译单元包含您的标头(前向声明hidde并定义public)和定义变量public pub;,但不能实际使用pub.d.v的任何成员。在C++17之前,仅仅包含头部就会触发未定义的行为。

 类似资料:
  • 这可能是一个愚蠢的问题,但是我很惊讶地看到,在外部类中不允许使用私有内部类作为泛型类型。 如果我使内部类受到保护,它编译得很好。 此外,我还必须精确而不仅仅是,否则找不到内部类。这看起来也有点奇怪。 为什么内心不能是私密的?为什么它被允许受到保护? 错误是: 我使用的是JavaSE17,但我认为它并没有太大用处。

  • 问题内容: 我听说过很多地方,PHP的。根据PHP5.3的LSB和闭包,我们没有理由依赖或。 有 什么 可能的情况是PHP 5.3中最好(唯一?)的答案? 这个问题 不是 关于邪恶是否普遍存在,因为显然不是。 答案摘要: 评估数值表达式(或PHP的其他“安全”子集) 单元测试 交互式PHP“外壳” 可信赖的反序列化 一些模板语言 为管理员和/或黑客创建后门 与<PHP 5.3的兼容性 检查语法(可

  • 这段代码的格式肯定不正确,因为是在实例化点之后专门化的: 由于我强调的标准的一部分,它是不正确的: 函数模板、成员函数模板、或类模板的成员函数或静态数据成员的专门化可以在翻译单元内具有多个实例化点,并且除了上述实例化点之外,对于在翻译单元内具有实例化点的任何这样的专门化,翻译单元的末尾也被认为是实例化点。类模板的专门化在翻译单元中最多有一个实例化点。任何模板的专门化都可能在多个翻译单元中具有实例化

  • 问题内容: ArrayList仅接受引用类型作为其元素,而不接受原始数据类型。尝试这样做时会产生编译时错误。 这背后的概念是什么?似乎是一个限制,不是吗? 问题答案: Java的所有收集类都存储它们收集的对象的内存位置。基本值不 适合 同一定义。 为避免此问题,JDK5及更高版本具有 自动装箱功能 -其中,将原语转换为适当的对象,然后在添加或从集合中读取原语时将其转换回原样。请参阅有关此主题的官方

  • 在爪哇,its说: 所以数组被称为协变的。但对于泛型,他们说: 因此它是不变的。但问题是,“泛型真的是不变的吗”? 那为什么说泛型是不变的呢?

  • 虽然有些人曾经问过这个问题,但那是在Java8发布之前。 以前,静态成员是不允许的,因为实现细节不能在接口中定义。这也是为什么任何东西都不应该是私有的,因为接口的实现者需要提供实现细节。 Java8改变了这种情况,不是吗?默认方法定义实现细节,静态方法也是如此。那么,为什么仍然不允许这样做呢?