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.