Tem*_*Rex 11 c++ templates language-lawyer c++11
考虑以下小代码片段:
#include <iostream>
template<class T>
int test();
int main()
{
std::cout << test<int>() << "\n";
}
// POI for test<int>() should be right here
template<class T>
int test()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
实例,为Clang和g ++编译并打印0.
14.6.4.1实例化点[temp.point]
1对于函数模板特化,成员函数模板特化,或成员函数或类模板的静态数据成员的特化,如果特化是隐式实例化的,因为它是从另一个模板特化和其中的上下文中引用的引用取决于模板参数,专门化的实例化点是封闭专门化的实例化点.否则,这种特化的实例化点紧跟在引用特化的命名空间范围声明或定义之后.
Vandevoorde和Josuttis对此有以下说法:
实际上,大多数编译器会将非内联函数模板的实际实例化延迟到翻译单元的末尾.这有效地将相应模板特化的POI移动到翻译单元的末尾.C++语言设计者的目的是使其成为一种有效的实现技术,但该标准并未明确这一点.
问题:Clang/g ++是否不符合要求,因为它们将POI延迟到翻译单元的末尾?
创建核心工作组缺陷报告993是为了解决此问题:
993.在翻译单位结束时自由进行实例化
条:14.6.4.1 [temp.point]状态:C++ 11发布者:John Spicer日期:2009年3月6日
[2011年3月会议上投票支持WP.]目的是在翻译单元的末尾而不是实际的实例化点进行模板实例化是一种允许的实现技术.然而,这个想法并没有反映在现行规则中.
拟议决议(2011年1月):
更改14.6.4.1 [临时点]第7段如下:
函数模板,成员函数模板或类模板的成员函数或静态数据成员的特化可以在翻译单元内具有多个实例化点,并且除了上述实例化的点之外,对于任何这样的实例化.在翻译单元内具有实例化点的专门化,翻译单元的末尾也被认为是实例化的点.类模板的专业化......
C++ 11中的第14.6.4.1/7段在N3936中为14.6.4.1/8:
函数模板,成员函数模板或类模板的成员函数或静态数据成员的特化可以在翻译单元内具有多个实例化点,并且除了上述实例化的点之外,对于任何这样的实例化.在翻译单元内具有实例化点的专门化,翻译单元的末尾也被认为是实例化的点.类模板的专门化在翻译单元中最多只有一个实例化点.任何模板的特化可以在多个翻译单元中具有实例化点.如果两个不同的实例化点根据一个定义规则(3.2)给出模板特化不同的含义,则程序是不正确的,不需要诊断.
所以是的,允许实现将模板实例化的时间延迟到翻译单元的末尾.