我想专门化一个功能模板。此函数在名称空间中声明:
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)进行编译:
在不同的命名空间[-fpermissive]
中的'template void foo :: function()'的特化
clang++ -std=c++11
接受此代码。
g ++也接受以下内容:
namespace foo
{
template <>
void function<0>()
{
}
}
谁是对的,gcc还是clang?
答案 0 :(得分:8)
根据标准§14.7.3/ 2,强调我的:
应在包含专用模板的命名空间中声明显式特化。一个明确的 declarator-id 非限定的特殊化应在最近的封闭命名空间中声明 模板,或者,如果命名空间是内联的(7.3.1),则来自其封闭的命名空间集的任何命名空间。
您必须将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