如何将不完整类型用作矢量模板参数?

Lig*_*ica 19 c++ language-lawyer c++11

TIL以下程序是合法的以及诸如此类的:

#include <vector>

struct Bar;

struct Foo
{
    using BarVec = std::vector<Bar>::size_type;
};

struct Bar {};

int main()
{
   Foo f;
}
Run Code Online (Sandbox Code Playgroud)

怎么样?Bar是一个不完整的类型,因此编译器无法知道std::vector<Bar>它是什么,或者它包含一个成员size_type,或者该成员size_type是一个类型.

我能想出的唯一解释是,任何假设的专业化(可能)都必须已经在范围内导致size_type与"基础"模板定义中给出的含义不同,并且size_type不是从属名称(两者都是有助于编译器确定性的因素).

这里的法律理由是什么?

Sha*_*our 12

我认为在实践中这可能有用,但从我可以看出这看起来像未定义的行为.从草案C++ 11标准17.6.4.8 [res.on.functions]:

特别是,在以下情况下,效果未定义:

[...]

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

虽然实例化模板组件似乎不是一个明确定义的术语.

我通过LWG缺陷611来到这里,它补充说:

除非特别允许该组件.

到上面的子弹的末尾所以它现在写道:

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

作为一个例外,shared_ptr因为上面的引用与20.6.6.2[util.smartptr.shared]中的引用冲突:

shared_ptr的模板参数T可以是不完整类型.

另请参阅N4371:标准容器的最小不完全类型支持,修订版2.