2011-05-06 125 views
5

考虑下面的例子:专业化模板函数

#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前面的函数定义会使错误消失。

回答

10

我认为这是未定义的行为根据标准。工具链在UB的情况下可以做什么没有限制,产生编译器错误是更友好的可能性之一。


[temp.spec],14.7p5说

对于给定的模板,一组给定的模板参数

  • 明确的实例化德网络nition应出现在最多一次一个程序,
  • 一个明确的专业化应该至多在程序中定义一次(根据到3.2)和
  • 显式实例化和显式特化的声明不应出现在 程序中,除非显式实例化遵循显式专用化的声明。

实施不需要诊断违反此规则。

[temp.expl.spec] 14.7.3p6说:

如果一个模板,一个成员模板或类模板的成员明确专门然后这个特应在第一次使用的是专业化的前申报这将导致在发生这种使用的每个翻译单元中发生隐含的实例化;不需要诊断。


你的程序违反了这些要求。

+0

+1为第二个报价。我正在寻找那个。 – Nawaz 2011-05-06 14:32:05

+0

是的,我正在寻找14.7.3。谢谢 – 2011-05-06 14:33:41