【问题标题】:Forward declaration of objects with STL containers使用 STL 容器前向声明对象
【发布时间】:2016-12-18 08:16:16
【问题描述】:

考虑以下代码 sn-p,其中第一行仅用作前向声明

 class A;

接着定义新的类

class B
{
 vector<A> Av;  //line 1
 map<int, A> Am;  //line 2
 pair<int, A> Ap; //line 3
};

第 1 行和第 2 行似乎可以使用前向声明(这可能会告诉我那些容器使用指针类型的实现),而第 3 行似乎无法在 VS2012 上编译。

我的问题是标准规定的行为还是我使用的编译器特定的行为?

【问题讨论】:

    标签: c++ visual-studio-2012 stl forward-declaration std-pair


    【解决方案1】:

    [作为巴里回答的补充说明]

    根据标准(C++17),实例化时只有std::vectorstd::liststd::forward_list可以用于不完整类型。

    §23.3.11.1/3 Class template vector overview [vector.overview]:

    如果分配器满足分配器完整性要求 [allocator.requirements.completeness],则在实例化 vector 时可以使用不完整类型 TT 应在 vector 的结果特化的任何成员被引用之前完成。

    §23.3.9.1/4 Class template forward_list overview [forwardlist.overview]:

    如果分配器满足分配器完整性要求 [allocator.requirements.completeness],则在实例化 forward_list 时可以使用不完整类型 TT 应在 forward_list 的结果特化的任何成员被引用之前完成。

    §23.3.10.1/3 Class template list overview [list.overview]:

    如果分配器满足分配器完整性要求 [allocator.requirements.completeness],则在实例化 list 时可以使用不完整类型 TT 应在 list 的结果特化的任何成员被引用之前完成。

    【讨论】:

      【解决方案2】:

      标准库类型的相关规则在[res.on.functions]:

      特别是,在以下情况下效果未定义:[...] 如果在实例化模板组件时将不完整类型 (3.9) 用作模板参数,除非该组件特别允许。

      这个:

      vector<A> Av;
      

      没问题。 std::vector 可以用不完整的类型实例化,只要它在您使用任何成员之前变得完整。 [vector.overview] 中的标准中有一个明确的例外:

      如果分配器满足分配器完整性,则在实例化 vector 时可能会使用不完整类型 T 要求 17.6.3.5.1。 T 应在产生的向量专业化的任何成员之前完成 被引用。

      std::liststd::forward_list 的措辞相似。

      这个:

      map<int, A> Am;
      

      格式不正确。 std::map 需要根据第一个引号在实例化点使用完整类型。这个容器也不例外,就像vector 一样。

      这个:

      pair<int, A> Ap;
      

      不可能永远工作,因为pair 只是一个有两个成员的简单结构。为了拥有A 类型的成员,您需要一个完整的类型。

      【讨论】:

      • 如果我没记错的话,已经为 C++17 添加了 vector、list 和 forward_list 的例外(我在 n4606 中找到它,但在 n3940 中没有;我不确定那是多少是当前实施状态的标准化,我似乎记得有人反对,但我没有像以前那样密切关注这个过程。
      • @AProgrammer 是的,它是N4510。虽然 libstdc++ 和 libc++ 已经允许这样做有一段时间了。
      • 谢谢巴里。这很有帮助
      【解决方案3】:

      不,这种行为是预期的和标准的。

      理由是std::pair实际上形成了一个结构,因此在实例化之前它的两个类型都必须是完整的。

      【讨论】:

      • “形成一个结构” 这个术语具有误导性/错误。
      猜你喜欢
      • 1970-01-01
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-16
      相关资源
      最近更新 更多