当函数模板专门化到不同的命名空间时,GCC和clang不同意



查看以下代码:

namespace ns {
template <typename T>
void func() {}
}
template <>
void ns::func<int>() {}
int main() {}

clang 3.6 (c++ 14)编译得很好,GCC 5.2 (c++ 14)抛出以下错误

main.cpp:9:20: error: specialization of 'template<class T> void ns::func()' in different namespace [-fpermissive]
 void ns::func<int>() {}
                    ^
main.cpp:4:6: error:   from definition of 'template<class T> void ns::func()' [-fpermissive]
 void func() {}
      ^

那么,标准是怎么说的呢?谁是正确的?

标准(n3797)是怎么说的?

14.7.3    Explicit Specialization    [temp.expl.spec]

显式专门化应在命名空间封闭中声明专门化模板。显式专门化,其declarator-id是不合格的,应该在最近的地方声明模板的封闭命名空间,或者,如果命名空间是内联的(7.3.1),它的封闭命名空间集中的任何命名空间。这样一个声明也可以是定义。如果声明不是定义时,可以稍后定义专门化(7.3.1.2)。

判定:你的专门化是显式专门化,并且它是限定的,这意味着代码段是合法的。因此,clang显示的行为是正确的。


gcc:

的相关bug报告
  • gcc.gnu.org/bugzilla - Bug 56480 -在包含特化模板的命名空间中显式特化

最新更新