查看以下代码:
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 -在包含特化模板的命名空间中显式特化