【问题标题】:std::vector on forward declared type前向声明类型上的 std::vector
【发布时间】:2015-09-11 21:20:39
【问题描述】:

以下代码似乎可以在 Clang++ 和 GCC 上正常工作:

#include <vector>

class A {
private:
    int i;
    std::vector<A> children;
public:
    A& add();
};

A& A::add() { children.emplace_back(); return children.back(); }

int main() {
    A a;
    A& a2 = a.add();
}

当声明数据成员std::vector&lt;A&gt;时,A仍然是一个不完整的类型。使用std::vector&lt;B&gt;B 时相同,仅使用class B; 前向声明。 它应该与std::vector 一起使用,因为它只包含一个指向A 的指针。

这是保证工作,还是未定义的行为?

【问题讨论】:

    标签: c++ c++11 stl forward-declaration c++17


    【解决方案1】:

    这是 C++14 及更早版本中未定义的行为;在 C++17 中定义良好(如果是 17)。

    [res.on.functions]/p2,第 2.7 条:

    特别是在以下情况下效果是不确定的:

    • [...]
    • 如果在实例化模板组件时将不完整类型 (3.9) 用作模板参数,除非特别允许 该组件。

    在 C++14 及更早版本中,std::vector 不“明确允许”此操作。所以行为是不确定的。

    对于 C++17,N4510 在委员会 2015 年 5 月的会议上通过,放宽了 vectorlistforward_list 的此规则。

    【讨论】:

      【解决方案2】:

      根据cppreference.com 中的“模板参数”部分,这可能在 C++17 标准中有效(取决于容器的实际使用情况),但在 C++14 及更早版本中无效。可能您正在使用实现这部分 C++17 标准的编译器版本。

      【讨论】:

      • 实际上,C++17 接受的论文只接受了 std::liststd::forward_liststd::vector,因此 GCC、Clang 和 MSVC 开箱即用。
      猜你喜欢
      • 2016-01-17
      • 1970-01-01
      • 2010-09-07
      • 1970-01-01
      • 1970-01-01
      • 2014-06-21
      • 2011-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多