命名空间中的函数模板专用化

function template specialization in a namespace

本文关键字:专用 函数模板 命名空间      更新时间:2023-10-16

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

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)进行编译:

不同命名空间中的"模板无效 foo::function()"的专业化 [-permissive]

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

G++ 也接受以下部分:

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

谁是对的,gcc 还是叮当?

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

应在包含专用模板的命名空间中声明显式专用化。一个明确的 声明符 ID不合格的专用化应在最近的封闭命名空间中声明 模板,或者,如果命名空间是内联的 (7.3.1),则为其封闭命名空间集中的任何命名空间。

你必须把template<> function<0>();放在namespace foo.但是,该规则仅适用于非限定声明符 ID。当您提供限定 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