命名空间中的函数模板特化

function template specialization in a namespace

我想特化一个函数模板。此函数在命名空间中声明:

namespace foo
{
   template <int>
   void function();
}

(为简单起见,模板基于 int,而在我的生产代码中,它是 enum class,但这是同一个问题。基于类型的情况也是如此模板)

现在我想将其专门化为特定值:

template <>
void foo::function<0>()
{
}

无法使用 g++ -std=c++11(版本 4.6、4.7、4.8 和 4.9)进行编译:

specialization of ‘template void foo::function()’ in different namespace [-fpermissive]

clang++ -std=c++11 接受此代码。

g++ 也接受以下部分:

namespace foo
{
   template <>
   void function<0>()
   {
   }
}

谁是对的,gcc 还是 clang?

根据标准,§14.7.3/2,强调我的:

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.

您必须将 template<> function<0>(); 放入 namespace foo。但是,该规则仅适用于未限定的 declarator-id。当您提供 qualified-id(如 foo::function<0> 中)时,我认为该条款不应适用,这使得这里的 clang 正确。

例如,给定 function 声明的问题,我希望得到以下结果:

namespace foo {
    template <> void function<0>(); // valid: unqualified explicit specialization
                                    // in the nearest enclosing namespace of the 
                                    // template
}

namespace bar {
    template <> void function<1>(); // invalid: unqualified explicit specialization
                                    // in the wrong namespace
}

struct baz {
    template <> void function<2>(); // invalid: unqualified explicit specialization
                                    // not in namespace scope
};

template <> void foo::function<3>(); // valid: qualified explicit specialization
                                     // is in a namespace, and id is qualified

template <> void bar::function<4>(); // invalid: there is no bar::function
                                     // to specialize