使用类作为具有正向延迟的 STL 类的模板参数

Using a class as a template parameter for a STL class with forward decleration

本文关键字:延迟 STL 参数      更新时间:2023-10-16

继续我在这里的问题:

我知道在向前减速后,例如

class Foo;

我可以将变量声明为 Foo*Foo& ,但不能声明 Foo ,如果我有一个模板化类Bar<T>里面只有T*T&,那么同样的规则将适用于Bar<Foo>(即我只需要正向减速即可编写Bar<Foo>)。

我的问题是 STL 类是否保证这样的事情,它们只包含对模板类型的引用和指针。我测试了这个:

class A;
std::vector<A> b;

STL 的 VS2010 实现并编译,但我不知道这是否适用于所有 STL 容器,也不知道这是否只是 STL 的 MS 实现方式,或者它是否是标准的一部分。

C++标准要求除少数类模板之外的所有类模板都有完整的类型(例如 std::shared_ptrstd::unique_ptr在某些特殊情况下)。容器需要完整类型,因此您的代码示例在技术上会产生未定义的行为,即使它可能适用于某些实现。

请注意,boost.container具有类似 std c++ 的容器,用于不完整的类型。

请参阅此相关 SO 帖子。

这在 17.6.4.8 [res.on.functions] 中列出,其中指定了未定义的行为

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

感谢@DietmarKühl找到合适的报价。

在 17.6.4.8 [res.on.functions] 第 2 段中指出

具体而言,在以下情况下未定义效果:

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

也就是说,标准库容器需要显式豁免,允许它们实例化某些类型不完整的类型。我很幸运,容器部分没有这样的例外。