...使用时没有模板参数错误

发布于 2024-11-06 08:21:35 字数 761 浏览 0 评论 0原文

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

我有以下代码,它导致非命名空间范围内的显式专业化错误:

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
}


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

I am in need of your help once again...

I had the following code, which was causing explicit specialization in non-namespace scope error:

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>'
    };
}



Since I already know how to fix this kind of errors, I defined specialization outside of the class scope, however I got another error - ... used without template parameters:

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



I'm probably just being stupid, but I don't understand the cause of this problem and I don't know how to fix it... Please help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倾城月光淡如水﹏ 2024-11-13 08:21:35

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

在类模板的成员或出现在命名空间范围中的成员模板的显式特化声明中,成员模板及其某些封闭类模板可能保持非特化,除非该声明不应显式特化类成员模板(如果其封闭类模板也未显式专门化)。在此类显式专业化声明中,应提供关键字 template 后跟 template-parameter-list,而不是提供前面的 template。成员的明确专业化声明。 template-parameter-list中的template-parameters类型应与主模板定义中指定的类型相同。


由于您明确专门化了成员函数模板而不是类成员模板,所以应该没问题;然而,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 说错误:包含模板参数列表的模板声明后面不能跟显式专业化声明,如果我们将 §14.7.3/18 中的规则也应用于成员函数模板,那么
  • GCC 会说在 '>' 之前显式特化无效令牌封闭类模板没有显式专门化,如果我们将 §14.7.3/18 中的规则也应用于成员函数模板,这又是有意义的,
  • VC++ 会显示 error C2768: 'test::Test< ;A,B,C>::check' :非法使用显式模板参数,这不是一个有用的错误消息,但通常与其他消息一致

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

By my reading of the standard, what you want to do appears to be legal. Quoting §14.7.3/18:

In an explicit specialization declaration for a member of a class template or a member template that appears in namespace scope, the member template and some of its enclosing class templates may remain unspecialized, except that the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well. In such explicit specialization declaration, the keyword template followed by a template-parameter-list shall be provided instead of the template<> preceding the explicit specialization declaration of the member. The types of the template-parameters in the template-parameter-list shall be the same as those specified in the primary template definition.

As you're explicitly specializing a member function template rather than a class member template, it should be fine; however, neither Comeau, GCC, nor VC++ allow the following, which should be correct syntax:

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 says error: a template declaration containing a template parameter list may not be followed by an explicit specialization declaration, which makes sense if we apply the rule in §14.7.3/18 to member function templates as well
  • GCC says invalid explicit specialization before '>' token; enclosing class templates are not explicitly specialized, which again makes sense if we apply the rule in §14.7.3/18 to member function templates as well
  • VC++ says error C2768: 'test::Test<A,B,C>::check' : illegal use of explicit template arguments, which isn't a helpful error message, but generally falls in line with the others

My guess is that there must be a defect report filed that also disallows explicit specializations of member function templates when the enclosing class templates are not explicitly specialized as well; however, I can't say this definitively since the wording for §14.7.3/18 hasn't changed between the C++03 standard and the C++0x FDIS (which it would if a DR was filed against C++03 and accepted).

ま昔日黯然 2024-11-13 08:21:35

您需要完全专门化所有内容,如下所示:

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);
    }
};

}

You need to either fully specialize everything, like this:

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 &)
{
}

}

Or use a helper structure to avoid trying to partially specialize template method of a template class (which GCC and many others won't understand):

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);
    }
};

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文