使用点后模板功能的专业化将打破编译

BЈо*_*вић 5 c++ specialization language-lawyer template-function

考虑下一个例子:

#include <iostream>

template< int a >
void foo();

int main(int argn, char* argv[])
{
    foo<1>();
}

template<>
void foo<1>()
{
    std::cout<<1<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)

编译失败,出现下一条错误消息:

rg.cpp:12: error: specialization of ‘void foo() [with int a = 1]’ after instantiation
Run Code Online (Sandbox Code Playgroud)

标准中的哪一段解释了这个错误?

PS:我知道如果我在main前面移动函数定义会使错误消失.

Ben*_*igt 10

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


[temp.spec]14.7p5 节说

对于给定的模板和给定的模板参数集,

  • 显式实例化定义最多只能在程序中出现一次,
  • 一个明确的专业化应该在一个程序中最多定义一次(根据3.2),和
  • 除非显式实例化遵循显式特化的声明,否则显式实例化和显式特化的声明都不应出现在程序中.

诊断违反此规则不需要实现.

[temp.expl.spec]14.7.3p6 节说:

如果模板,成员模板或类模板的成员是显式专用的,则应在首次使用该特化之前声明该特化,这将导致发生隐式实例化,在发生此类使用的每个翻译单元中; 无需诊断.


您的程序违反了这些要求.