..在没有模板参数错误的情况下使用

... used without template parameters error

本文关键字:情况下 错误 参数      更新时间:2023-10-16

我再次需要你的帮助...

我有以下代码,这导致非命名空间范围错误的显式专用化

namespace __test
{
    template <int A, int B, typename C> class Test
    {
        template <int V> void check(C & a) { }
        template <> void check<0>(C & a) { } //error: explicit specialization in non-namespace scope 'class __test::Test<A, B, C>'
    };
}


由于我已经知道如何修复此类错误,因此我在类范围之外定义了专用化,但是我遇到了另一个错误 - ...不带模板参数使用

namespace __test
{
    template <> void Test::check<0>(C & a) { } //error: 'template<int A, int B, class C> class __test::Test' used without template parameters
}


我可能只是愚蠢,但我不明白这个问题的原因,我不知道如何解决它......请帮忙!

根据我对标准的解读,你想做的事情似乎是合法的。引用 §14.7.3/18:

在类模板的成员

或出现在命名空间作用域中的成员模板的显式专用化声明中,成员模板及其某些封闭类模板可能保持非专用化状态,但如果类成员模板的封闭类模板也未显式专用化,则声明不得显式专用化类成员模板。在这种明确的专用化声明中,应提供关键字template后跟模板-参数-列表,而不是成员显式专用化声明之前的template<>。模板参数列表中的模板参数类型应与主模板定义中指定的类型相同。

由于您显式专用于成员函数模板而不是类成员模板,因此应该没问题;但是,Comeau、GCC 和 VC++ 都不允许以下内容,这应该是正确的语法:

namespace test
{
    template<int A, int B, typename C>
    class Test
    {
        template<int V>
        void check(C& a) { }
    };
    template<int A, int B, typename C>
    template<>
    void Test<A, B, C>::check<0>(C& a) { }
}
  • Comeau 说error: a template declaration containing a template parameter list may not be followed by an explicit specialization declaration ,如果我们将 §14.7.3/18 中的规则也应用于成员函数模板,这是有意义的
  • 海湾合作委员会说invalid explicit specialization before '>' token; enclosing class templates are not explicitly specialized ,如果我们将 §14.7.3/18 中的规则也应用于成员函数模板,这又是有意义的
  • VC++说error C2768: 'test::Test<A,B,C>::check' : illegal use of explicit template arguments,这不是一个有用的错误消息,但通常与其他错误消息一致

我的猜测是,当封闭类模板没有明确专用时,必须提交一份缺陷报告,该报告也不允许成员函数模板的显式专用化; 但是,我不能明确地说,因为§14.7.3/18的措辞在C++03标准和C++0x FDIS之间没有变化(如果针对C++03提交DR并被接受,则会改变)。

你需要完全专业化所有内容,就像这样:

namespace __test {
template <int A, int B, typename C>
class Test
{
    template <int V> void check(C & a) { }
};
template <>
template <>
void Test<1, 2, int>::check<0> (int &)
{
}
}

或者使用帮助程序结构来避免尝试部分专用化模板类的模板方法(GCC 和许多其他人不会理解):

namespace __test {
template <typename C, int V>
struct TestHelper
{
    static void check (C & a)
    {
    }
};
template <typename C>
struct TestHelper<C, 0>
{
    static void check (C & a)
    {
    }
};
template <int A, int B, typename C>
class Test
{
    template <int V> void check(C & a)
    {
        TestHelper<C, V>::check (a);
    }
};
}
相关文章: