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

When function template is specialized in a different namespace, GCC and clang disagree

见以下代码:

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    <b>Explicit Specialization</b>    [temp.expl.spec]

An explicit specialization shall be declared in a namespace enclosing the specialized template. An explicit specialization whose declarator-id is not qualified shall be declared in the nearest enclosing namespace of the template, or, if the namespace is inline (7.3.1), any namespace from its enclosing namespace set. Such a declaration may also be a definition. If the declaration is not a definition, the specialization may be defined later (7.3.1.2).

Verdict:您的专业是显式专业,并且合格,意思是该片段是合法的。因此,clang 显示的行为是正确的。


gcc的相关错误报告: