考虑下一个例子:
#include <iostream>
template< int a >
void foo();
int main(int argn, char* argv[])
{
foo<1>();
}
template<>
void foo<1>()
{
std::cout<<1<<std::endl;
}
编译失败并显示以下错误消息:
rg.cpp:12: error: specialization of ‘void foo() [with int a = 1]’ after instantiation
标准中的哪一段解释了这个错误?
PS :我知道如果我将函数定义移到 main 前面将使错误消失。
最佳答案
根据标准,我认为这是未定义的行为。在 UB 的情况下,工具链可以做什么没有限制,生成编译器错误是一种更友好的可能性。
[temp.spec]
部分,14.7p5 说
For a given template and a given set of template-arguments,
- an explicit instantiation definition shall appear at most once in a program,
- an explicit specialization shall be defined at most once in a program (according to 3.2), and
- both an explicit instantiation and a declaration of an explicit specialization shall not appear in a program unless the explicit instantiation follows a declaration of the explicit specialization.
An implementation is not required to diagnose a violation of this rule.
部分 [temp.expl.spec]
14.7.3p6 说:
If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required.
您的程序违反了这些要求。
关于c++ - 使用点后模板函数的特化会破坏编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5912689/