c++ - 使用点后模板函数的特化会破坏编译

标签 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;
}

编译失败并显示以下错误消息:

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/

相关文章:

c++ - 为什么 lambda 会删除 cv 和 ref?

c++ - 当 Font 是一个类时, 'Font(..)' 是什么意思?

c# - 将 C++ (DLL) 与 C# 控制台应用程序互操作时出现问题

C++ - 使用默认模板作为特化的基础

c++ - 可变递归模板 mem 有趣的特化

c - 如果您知道字符会在到达有效区域末尾之前找到,那么调用长度过长的 memchr 是否合法?

c++ - 预分配内存列表

c++ - 如何整理/修复PyCXX创建的新型Python扩展类?

c++ - 使用部分模板类作为专门的模板函数

python - 为什么我不能将 self 作为命名参数传递给 Python 中的实例方法?